From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) by sourceware.org (Postfix) with ESMTPS id 8D70C3858C5E for ; Thu, 2 Feb 2023 23:30:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8D70C3858C5E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-IronPort-AV: E=Sophos;i="5.97,268,1669104000"; d="scan'208";a="95485830" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 02 Feb 2023 15:30:50 -0800 IronPort-SDR: u9O8WlZGppryNOKCYtM5b2tlxFu8NFVrg8dklJ7FAhaijF88k8G3M6kNeL9uy8CeQlRrdxWPtL 3mz1Uc2uXiTCUbd8gpjgCg4lB0CvxNEIRHFqSv326Wu/q+QTve5kC9zglqzw4Fw4HhqScYPxc/ VyhgNo0P5+LZhYcSuWYUddaG+LgbH3LSvU9reAWNeni/wQtBI751mSwjTLHwwNc+UxlZ2KIZco kXtdWOXorYRs/0LMkJegNVkUYmXpd1+PyhY3n4uVPri73lnqhhcXLAEDiMfr5Zm52RRVm8HsVY nOQ= Date: Thu, 2 Feb 2023 23:30:44 +0000 From: Joseph Myers To: Subject: [committed] c: Update nullptr_t comparison checks Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) To svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) X-Spam-Status: No, score=-3114.6 required=5.0 tests=BAYES_00,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,KAM_DMARC_STATUS,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: WG14 has agreed to allow equality comparisons between pointers and nullptr_t values that are not null pointer constants (this was previously an exceptional case where such nullptr_t values were handled differently from null pointer constants; other places in the standard allowed nullptr_t values, whether or not those values are null pointer constants, in the same contexts as null pointer constants); see the wording at the end of N3077. Update GCC's implementation to match this change. There are also changes to allow null pointer constants of integer or pointer type to be converted to nullptr_t (by assignment, cast or conversion as if by assignment), which I'll deal with separately. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c/ * c-typeck.cc (build_binary_op): Allow comparisons between pointers and nullptr_t values that are not null pointer constants. gcc/testsuite/ * gcc.dg/c2x-constexpr-3.c: Do not expect comparison of nullptr_t and pointer to be disallowed. * gcc.dg/c2x-nullptr-1.c: Test comparisons of nullptr_t and pointers are allowed. * gcc.dg/c2x-nullptr-3.c: Do not test that comparisons of nullptr_t and pointers are disallowed. diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 9d65130154d..224a9cbdc3d 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -12749,12 +12749,16 @@ build_binary_op (location_t location, enum tree_code code, && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE)) short_compare = 1; - else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) + else if (code0 == POINTER_TYPE + && (code1 == NULLPTR_TYPE + || null_pointer_constant_p (orig_op1))) { maybe_warn_for_null_address (location, op0, code); result_type = type0; } - else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) + else if (code1 == POINTER_TYPE + && (code0 == NULLPTR_TYPE + || null_pointer_constant_p (orig_op0))) { maybe_warn_for_null_address (location, op1, code); result_type = type1; diff --git a/gcc/testsuite/gcc.dg/c2x-constexpr-3.c b/gcc/testsuite/gcc.dg/c2x-constexpr-3.c index 4f6b8ed6779..44a3ed358e1 100644 --- a/gcc/testsuite/gcc.dg/c2x-constexpr-3.c +++ b/gcc/testsuite/gcc.dg/c2x-constexpr-3.c @@ -219,7 +219,6 @@ f0 () (constexpr signed char []) { u8"\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */ constexpr typeof (nullptr) not_npc = nullptr; int *ptr = 0; - (void) (ptr == not_npc); /* { dg-error "invalid operands" } */ /* auto may only be used with another storage class specifier, such as constexpr, if the type is inferred. */ auto constexpr int a_c_t = 1; /* { dg-error "'auto' used with 'constexpr'" } */ diff --git a/gcc/testsuite/gcc.dg/c2x-nullptr-1.c b/gcc/testsuite/gcc.dg/c2x-nullptr-1.c index 9f2cb6c8256..04f9901bb12 100644 --- a/gcc/testsuite/gcc.dg/c2x-nullptr-1.c +++ b/gcc/testsuite/gcc.dg/c2x-nullptr-1.c @@ -141,6 +141,23 @@ test2 (int *p) (void) (p != _Generic(0, int : nullptr)); (void) (_Generic(0, int : nullptr) == p); (void) (_Generic(0, int : nullptr) != p); + + /* "(nullptr_t)nullptr" has type nullptr_t but isn't an NPC; these + comparisons are valid after C2X CD comments GB-071 and FR-073 were + resolved by the wording in N3077. */ + (void) ((nullptr_t)nullptr == p); + (void) ((nullptr_t)nullptr != p); + (void) (p == (nullptr_t)nullptr); + (void) (p != (nullptr_t)nullptr); + (void) (cmp () == p); + (void) (cmp () != p); + (void) (p == cmp ()); + (void) (p != cmp ()); + /* "(void *)nullptr" is not an NPC, either. */ + (void) ((void *)nullptr == cmp ()); + (void) ((void *)nullptr != cmp ()); + (void) (cmp () == (void *)nullptr); + (void) (cmp () != (void *)nullptr); } /* Test ?:. */ diff --git a/gcc/testsuite/gcc.dg/c2x-nullptr-3.c b/gcc/testsuite/gcc.dg/c2x-nullptr-3.c index 34e3e03ba9d..591ab7e6158 100644 --- a/gcc/testsuite/gcc.dg/c2x-nullptr-3.c +++ b/gcc/testsuite/gcc.dg/c2x-nullptr-3.c @@ -19,21 +19,6 @@ test1 (int *p) (void) (nullptr != 1); /* { dg-error "invalid operands" } */ (void) (1 != nullptr); /* { dg-error "invalid operands" } */ (void) (1 > nullptr); /* { dg-error "invalid operands" } */ - - /* "(nullptr_t)nullptr" has type nullptr_t but isn't an NPC. */ - (void) ((nullptr_t)nullptr == p); /* { dg-error "invalid operands" } */ - (void) ((nullptr_t)nullptr != p); /* { dg-error "invalid operands" } */ - (void) (p == (nullptr_t)nullptr); /* { dg-error "invalid operands" } */ - (void) (p != (nullptr_t)nullptr); /* { dg-error "invalid operands" } */ - (void) (cmp () == p); /* { dg-error "invalid operands" } */ - (void) (cmp () != p); /* { dg-error "invalid operands" } */ - (void) (p == cmp ()); /* { dg-error "invalid operands" } */ - (void) (p != cmp ()); /* { dg-error "invalid operands" } */ - /* "(void *)nullptr" is not an NPC, either. */ - (void) ((void *)nullptr == cmp ()); /* { dg-error "invalid operands" } */ - (void) ((void *)nullptr != cmp ()); /* { dg-error "invalid operands" } */ - (void) (cmp () == (void *)nullptr); /* { dg-error "invalid operands" } */ - (void) (cmp () != (void *)nullptr); /* { dg-error "invalid operands" } */ } void -- Joseph S. Myers joseph@codesourcery.com