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