From patchwork Mon Jan 8 12:31:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 856781 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-88927-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="K+RJBW2Z"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zFZQ35F9bz9sBZ for ; Mon, 8 Jan 2018 23:31:23 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; q=dns; s=default; b= MXJWPowpCe0xWxU/WHo4E4m5XqFGHAzO7NpKXG2o1wYDYNLjgptWJht3+9VeQTBg LFYWko8erkc3bKn4kLHfYmxtFdIck1CVgOS1g9uWXr5RwhIgp24wDGPTB1TiOldJ wpOUpCfk57/4Jg94P1Xl3V/vdDU8AIOtTY5/14Vldkg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; s=default; bh=iLU9M6 Qbdvs5i+EQaCBigerdJps=; b=K+RJBW2Zil5qZ8tinu+vsgeZj2iCzBzaereBOo w9J6L69CgRHWOFlVH3zR30k8iJ6HtLwF1FWfpiKJ2xpvEx7OT7IYNEFiD2+RGDGf 9AqN+ydNZpQXgjNrse4Lv9XICB5T+inFTxnPl2xsuTJtYY97wfPI8fO9nP29xCEO tbw1M= Received: (qmail 70049 invoked by alias); 8 Jan 2018 12:31:17 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 70035 invoked by uid 89); 8 Jan 2018 12:31:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Compression, 3711 X-HELO: mx1.redhat.com Date: Mon, 08 Jan 2018 13:31:11 +0100 To: libc-alpha@sourceware.org Subject: [PATCH] support: Increase usability of TEST_COMPARE User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20180108123111.2CD4B4018908A@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) The previous implementation of the TEST_COMPARE macro would fail to compile code like this: int ret = res_send (query, sizeof (query), buf, sizeof (buf)); TEST_COMPARE (ret, sizeof (query) + 2 /* Compression reference. */ + 2 + 2 + 4 + 2 /* Type, class, TTL, RDATA length. */ + 1 /* Pascal-style string length. */ + strlen (expected_name)); This resulted in a failed static assertion, "integer conversions may alter sign of operands". A user of the TEST_COMPARE would have to add a cast to fix this. This patch reverts to the original proposed solution of a run-time check, making TEST_COMPARE usable for comparisons of numbers with types with different signedness in more contexts. 2018-01-08 Florian Weimer * support/check.h (TEST_COMPARE): Allow sign mismatch at compile time. Pass positive flag instead of negative flag to support_test_compare_failure. (support_test_compare_failure): Change negative parameter to positive. * support/support_test_compare_failure.c (report) (support_test_compare_failure): Likewise. * support/tst-test_compare.c (return_ssize_t, return_int): New. (do_test): Check int/size_t, ssize_t/size_t comparisons. Reviewed-by: Carlos O'Donell diff --git a/support/check.h b/support/check.h index de8fce0dc1..2ac25a187c 100644 --- a/support/check.h +++ b/support/check.h @@ -95,7 +95,9 @@ void support_record_failure (void); typedef __typeof__ (+ (right)) __right_type; \ __left_type __left_value = (left); \ __right_type __right_value = (right); \ - /* Prevent use with floating-point and boolean types. */ \ + int __left_is_positive = __left_value > 0; \ + int __right_is_positive = __right_value > 0; \ + /* Prevent use with floating-point types. */ \ _Static_assert ((__left_type) 1.0 == (__left_type) 1.5, \ "left value has floating-point type"); \ _Static_assert ((__right_type) 1.0 == (__right_type) 1.5, \ @@ -105,33 +107,18 @@ void support_record_failure (void); "left value fits into long long"); \ _Static_assert (sizeof (__right_value) <= sizeof (long long), \ "right value fits into long long"); \ - /* Make sure that integer conversions does not alter the sign. */ \ - enum \ - { \ - __left_is_unsigned = (__left_type) -1 > 0, \ - __right_is_unsigned = (__right_type) -1 > 0, \ - __unsigned_left_converts_to_wider = (__left_is_unsigned \ - && (sizeof (__left_value) \ - < sizeof (__right_value))), \ - __unsigned_right_converts_to_wider = (__right_is_unsigned \ - && (sizeof (__right_value) \ - < sizeof (__left_value))) \ - }; \ - _Static_assert (__left_is_unsigned == __right_is_unsigned \ - || __unsigned_left_converts_to_wider \ - || __unsigned_right_converts_to_wider, \ - "integer conversions may alter sign of operands"); \ /* Compare the value. */ \ - if (__left_value != __right_value) \ + if (__left_value != __right_value \ + || __left_is_positive != __right_is_positive) \ /* Pass the sign for printing the correct value. */ \ support_test_compare_failure \ (__FILE__, __LINE__, \ - #left, __left_value, __left_value < 0, sizeof (__left_type), \ - #right, __right_value, __right_value < 0, sizeof (__right_type)); \ + #left, __left_value, __left_is_positive, sizeof (__left_type), \ + #right, __right_value, __right_is_positive, sizeof (__right_type)); \ }) -/* Internal implementation of TEST_COMPARE. LEFT_NEGATIVE and - RIGHT_NEGATIVE are used to store the sign separately, so that both +/* Internal implementation of TEST_COMPARE. LEFT_POSITIVE and + RIGHT_POSITIVE are used to store the sign separately, so that both unsigned long long and long long arguments fit into LEFT_VALUE and RIGHT_VALUE, and the function can still print the original value. LEFT_SIZE and RIGHT_SIZE specify the size of the argument in bytes, @@ -139,11 +126,11 @@ void support_record_failure (void); void support_test_compare_failure (const char *file, int line, const char *left_expr, long long left_value, - int left_negative, + int left_positive, int left_size, const char *right_expr, long long right_value, - int right_negative, + int right_positive, int right_size); diff --git a/support/support_test_compare_failure.c b/support/support_test_compare_failure.c index a789283f86..e5596fd121 100644 --- a/support/support_test_compare_failure.c +++ b/support/support_test_compare_failure.c @@ -20,14 +20,14 @@ #include static void -report (const char *which, const char *expr, long long value, int negative, +report (const char *which, const char *expr, long long value, int positive, int size) { printf (" %s: ", which); - if (negative) - printf ("%lld", value); - else + if (positive) printf ("%llu", (unsigned long long) value); + else + printf ("%lld", value); unsigned long long mask = (~0ULL) >> (8 * (sizeof (unsigned long long) - size)); printf (" (0x%llx); from: %s\n", (unsigned long long) value & mask, expr); @@ -37,11 +37,11 @@ void support_test_compare_failure (const char *file, int line, const char *left_expr, long long left_value, - int left_negative, + int left_positive, int left_size, const char *right_expr, long long right_value, - int right_negative, + int right_positive, int right_size) { support_record_failure (); @@ -50,6 +50,6 @@ support_test_compare_failure (const char *file, int line, file, line, left_size * 8, right_size * 8); else printf ("%s:%d: numeric comparison failure\n", file, line); - report (" left", left_expr, left_value, left_negative, left_size); - report ("right", right_expr, right_value, right_negative, right_size); + report (" left", left_expr, left_value, left_positive, left_size); + report ("right", right_expr, right_value, right_positive, right_size); } diff --git a/support/tst-test_compare.c b/support/tst-test_compare.c index 340268fadf..123ba1bc3c 100644 --- a/support/tst-test_compare.c +++ b/support/tst-test_compare.c @@ -42,6 +42,22 @@ struct bitfield unsigned long long int u63 : 63; }; +/* Functions which return signed sizes are common, so test that these + results can readily checked using TEST_COMPARE. */ + +static int +return_ssize_t (void) +{ + return 4; +} + +static int +return_int (void) +{ + return 4; +} + + static int do_test (void) { @@ -53,6 +69,8 @@ do_test (void) unsigned short u16 = 3; TEST_COMPARE (i8, u16); } + TEST_COMPARE (return_ssize_t (), sizeof (char[4])); + TEST_COMPARE (return_int (), sizeof (char[4])); struct bitfield bitfield = { 0 }; TEST_COMPARE (bitfield.i2, bitfield.i3);