public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-5767] c: Allow conversions of null pointer constants to nullptr_t
@ 2023-02-10  0:43 Joseph Myers
  0 siblings, 0 replies; only message in thread
From: Joseph Myers @ 2023-02-10  0:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b9f8935e110c392c21460db838b4209c32f070c2

commit r13-5767-gb9f8935e110c392c21460db838b4209c32f070c2
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri Feb 10 00:42:47 2023 +0000

    c: Allow conversions of null pointer constants to nullptr_t
    
    WG14 has agreed to allow conversions (explicit and implicit) from null
    pointer constants to nullptr_t; update GCC's nullptr_t implementation
    to match.
    
    Bootstrapped with no regressions for x86_64-pc-linux-gnu.
    
    gcc/c/
            * c-convert.cc (c_convert): Allow conversion of a null pointer
            constant to nullptr_t.
            * c-typeck.cc (null_pointer_constant_p): Remove static.
            (convert_for_assignment): Allow conversion of a null pointer
            constant to nullptr_t.
            (digest_init): Handle NULLPTR_TYPE among scalar conversions.
            * c-tree.h (null_pointer_constant_p): Declare.
    
    gcc/testsuite/
            * gcc.dg/c2x-nullptr-1.c: Test conversion of null pointer
            constants to nullptr_t.
            * gcc.dg/c2x-nullptr-3.c: Do not expect errors for conversion of
            null pointer constants to nullptr_t.  Do test errors for
            conversion of other values to nullptr_t and for unary '+' on
            nullptr_t.

Diff:
---
 gcc/c/c-convert.cc                   | 21 ++++++++++++++++++---
 gcc/c/c-tree.h                       |  1 +
 gcc/c/c-typeck.cc                    |  7 ++++---
 gcc/testsuite/gcc.dg/c2x-nullptr-1.c | 16 ++++++++++++++--
 gcc/testsuite/gcc.dg/c2x-nullptr-3.c | 19 +++++++++++--------
 5 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/gcc/c/c-convert.cc b/gcc/c/c-convert.cc
index dccd245dfc3..0f35dc4fe9a 100644
--- a/gcc/c/c-convert.cc
+++ b/gcc/c/c-convert.cc
@@ -157,6 +157,19 @@ c_convert (tree type, tree expr, bool init_const)
       ret = convert_to_pointer (type, e);
       goto maybe_fold;
 
+    case NULLPTR_TYPE:
+      /* A null pointer constant or value of type nullptr_t may be
+	 converted to nullptr_t.  The latter case has already been
+	 handled.  build_c_cast will create an additional NOP_EXPR to
+	 ensure the result of the conversion is not itself a null
+	 pointer constant.  */
+      if (null_pointer_constant_p (expr))
+	{
+	  ret = build_int_cst (type, 0);
+	  goto maybe_fold;
+	}
+      break;
+
     case REAL_TYPE:
       ret = convert_to_real (type, e);
       goto maybe_fold;
@@ -201,12 +214,14 @@ c_convert (tree type, tree expr, bool init_const)
     }
 
   /* If we are converting to nullptr_t, don't say "non-scalar type" because
-     the nullptr_t type is a scalar type.  Only nullptr_t shall be converted
-     to nullptr_t.  */
+     the nullptr_t type is a scalar type.  Only nullptr_t or a null pointer
+     constant shall be converted to nullptr_t.  */
   if (code == NULLPTR_TYPE)
     {
       error ("conversion from %qT to %qT", TREE_TYPE (e), type);
-      inform (input_location, "only %qT can be converted to %qT", type, type);
+      inform (input_location,
+	      "only %qT or a null pointer constant can be converted to %qT",
+	      type, type);
     }
   else
     error ("conversion to non-scalar type requested");
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 00ccf87e6e6..e5eefe6bbba 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -728,6 +728,7 @@ extern location_t c_last_sizeof_loc;
 
 extern struct c_switch *c_switch_stack;
 
+extern bool null_pointer_constant_p (const_tree);
 extern bool char_type_p (tree);
 extern tree c_objc_common_truthvalue_conversion (location_t, tree);
 extern tree require_complete_type (location_t, tree);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 157b77eda95..e37b0973cd6 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -89,7 +89,6 @@ static bool require_constant_value;
 static bool require_constant_elements;
 static bool require_constexpr_value;
 
-static bool null_pointer_constant_p (const_tree);
 static tree qualify_type (tree, tree);
 static int tagged_types_tu_compatible_p (const_tree, const_tree, bool *,
 					 bool *);
@@ -130,7 +129,7 @@ static int comptypes_internal (const_tree, const_tree, bool *, bool *);
 \f
 /* Return true if EXP is a null pointer constant, false otherwise.  */
 
-static bool
+bool
 null_pointer_constant_p (const_tree expr)
 {
   /* This should really operate on c_expr structures, but they aren't
@@ -7837,6 +7836,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
       in_late_binary_op = save;
       return ret;
     }
+  else if (codel == NULLPTR_TYPE && null_pointer_constant)
+    return convert (type, rhs);
 
   switch (errtype)
     {
@@ -8596,7 +8597,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 
   if (code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE
       || code == POINTER_TYPE || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
-      || code == COMPLEX_TYPE || code == VECTOR_TYPE)
+      || code == COMPLEX_TYPE || code == VECTOR_TYPE || code == NULLPTR_TYPE)
     {
       tree unconverted_init = inside_init;
       if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
diff --git a/gcc/testsuite/gcc.dg/c2x-nullptr-1.c b/gcc/testsuite/gcc.dg/c2x-nullptr-1.c
index 04f9901bb12..4e440234d52 100644
--- a/gcc/testsuite/gcc.dg/c2x-nullptr-1.c
+++ b/gcc/testsuite/gcc.dg/c2x-nullptr-1.c
@@ -11,8 +11,9 @@ void f2 (int *) { }
 void f3 (_Bool) { }
 nullptr_t cmp (void) { return nullptr; }
 
-/* The type nullptr_t shall not be converted to any type other than void, bool or
-   a pointer type.  No type other than nullptr_t shall be converted to nullptr_t.  */
+/* The type nullptr_t shall not be converted to any type other than void, bool
+   or a pointer type.  No type other than nullptr_t or a null pointer constant
+   shall be converted to nullptr_t.  */
 void
 test1 (void)
 {
@@ -63,6 +64,17 @@ test1 (void)
   (void) np2;
   (void) cmp ();
   (void)(nullptr_t) nullptr;
+
+  const nullptr_t n = 0;
+  (void) (nullptr_t) 0;
+
+  f1 (0);
+  f1 ((void *) 0);
+  f1 (0L);
+  nullptr_t n2;
+  n2 = (void *) 0;
+  n2 = 123 - 123;
+  (void) n2;
 }
 
 /* Test valid comparison.  */
diff --git a/gcc/testsuite/gcc.dg/c2x-nullptr-3.c b/gcc/testsuite/gcc.dg/c2x-nullptr-3.c
index 591ab7e6158..09d9856ef97 100644
--- a/gcc/testsuite/gcc.dg/c2x-nullptr-3.c
+++ b/gcc/testsuite/gcc.dg/c2x-nullptr-3.c
@@ -29,21 +29,24 @@ test2 (void)
   float d = nullptr; /* { dg-error "incompatible types" } */
   char arr[10] = { nullptr }; /* { dg-error "incompatible types" } */
 
-  /* No type other than nullptr_t shall be converted to nullptr_t.  */
-  const nullptr_t n = 0; /* { dg-error "invalid initializer" } */
-  +(nullptr_t) 0; /* { dg-error "conversion from .int. to .nullptr_t." } */
-
-  g (0); /* { dg-error "incompatible type" } */
+  /* Unary '+' is not valid for nullptr.  */
+  +nullptr; /* { dg-error "wrong type argument to unary plus" } */
 
+  g (0.0); /* { dg-error "incompatible type" } */
+  g (1); /* { dg-error "incompatible type" } */
+  g ((int) (float) 0.0); /* { dg-error "incompatible type" } */
   int i = 42 + nullptr; /* { dg-error "invalid operands" } */
 
   /* The assignment of an object of type nullptr_t with a value of another
-     type, even if the value is a null pointer constant, is a constraint
+     type, other than a null pointer constant, is a constraint
      violation.  */
   nullptr_t m;
-  m = 0; /* { dg-error "incompatible types" } */
+  m = 1; /* { dg-error "incompatible types" } */
+  m = 0.0; /* { dg-error "incompatible types" } */
   (void) m;
-  nullptr_t o = 0; /* { dg-error "invalid initializer" } */
+  nullptr_t o = 1; /* { dg-error "incompatible types" } */
+  (nullptr_t) 0.0; /* { dg-error "conversion" } */
+  (nullptr_t) (int) (float) 0.0; /* { dg-error "conversion" } */
 
   switch (nullptr); /* { dg-error "switch quantity not an integer" } */
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-10  0:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-10  0:43 [gcc r13-5767] c: Allow conversions of null pointer constants to nullptr_t Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).