public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] reject scalar array initialization with nullptr [PR94510]
@ 2020-04-07 18:50 Martin Sebor
  2020-04-07 19:50 ` Marek Polacek
  2020-04-08 18:43 ` Jason Merrill
  0 siblings, 2 replies; 22+ messages in thread
From: Martin Sebor @ 2020-04-07 18:50 UTC (permalink / raw)
  To: gcc-patches, Jason Merrill

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

Among the numerous regressions introduced by the change committed
to GCC 9 to allow string literals as template arguments is a failure
to recognize the C++ nullptr and GCC's __null constants as pointers.
For one, I didn't realize that nullptr, being a null pointer constant,
doesn't have a pointer type, and two, I didn't think of __null (which
is a special integer constant that NULL sometimes expands to).

The attached patch adjusts the special handling of trailing zero
initializers in reshape_init_array_1 to recognize both kinds of
constants and avoid treating them as zeros of the array integer
element type.  This restores the expected diagnostics when either
constant is used in the initializer list.

Martin

[-- Attachment #2: gcc-94510.diff --]
[-- Type: text/x-patch, Size: 3527 bytes --]

PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

	PR c++/94510
	* decl.c (reshape_init_array_1): Exclude mismatches with all kinds
	of pointers.

gcc/testsuite/ChangeLog:

	PR c++/94510
	* g++.dg/init/array57.C: New test.
	* g++.dg/init/array58.C: New test.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a127734af69..692c8ed73f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6041,9 +6041,14 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
 	TREE_CONSTANT (new_init) = false;
 
       /* Pointers initialized to strings must be treated as non-zero
-	 even if the string is empty.  */
+	 even if the string is empty.  Handle all kinds of pointers,
+	 including std::nullptr and GCC's __nullptr, neither of which
+	 has a pointer type.  */
       tree init_type = TREE_TYPE (elt_init);
-      if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
+      bool init_is_ptr = (POINTER_TYPE_P (init_type)
+			  || NULLPTR_TYPE_P (init_type)
+			  || null_node_p (elt_init));
+      if (POINTER_TYPE_P (elt_type) != init_is_ptr
 	  || !type_initializer_zero_p (elt_type, elt_init))
 	last_nonzero = index;
 
diff --git a/gcc/testsuite/g++.dg/init/array57.C b/gcc/testsuite/g++.dg/init/array57.C
new file mode 100644
index 00000000000..fdd7e76eb18
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array57.C
@@ -0,0 +1,15 @@
+/* PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array
+   { dg-do compile } */
+
+int ia1[2] = { (void*)0 };              // { dg-error "invalid conversion from 'void\\\*'" }
+int ia2[2] = { (void*)0, 0 };           // { dg-error "invalid conversion from 'void\\\*'" }
+int ia3[] = { (void*)0, 0 };            // { dg-error "invalid conversion from 'void\\\*'" }
+
+int ia4[2] = { __null };                // { dg-warning "\\\[-Wconversion-null" }
+int ia5[2] = { __null, 0 };             // { dg-warning "\\\[-Wconversion-null" }
+int ia6[] = { __null, 0 };              // { dg-warning "\\\[-Wconversion-null" }
+
+
+const char ca1[2] = { (char*)0, 0 };    // { dg-error "invalid conversion from 'char\\\*'" }
+
+const char ca2[2] = { __null, 0 };      // { dg-warning "\\\[-Wconversion-null" }
diff --git a/gcc/testsuite/g++.dg/init/array58.C b/gcc/testsuite/g++.dg/init/array58.C
new file mode 100644
index 00000000000..655e08fa600
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array58.C
@@ -0,0 +1,21 @@
+/* PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array
+   { dg-do compile { target c++11 } } */
+
+namespace std {
+typedef __typeof__ (nullptr) nullptr_t;
+}
+
+int ia1[2] = { nullptr };                 // { dg-error "cannot convert 'std::nullptr_t' to 'int'" }
+int ia2[2] = { nullptr, 0 };              // { dg-error "cannot convert 'std::nullptr_t' to 'int'" }
+int ia3[] = { nullptr, 0 };               // { dg-error "cannot convert 'std::nullptr_t' to 'int'" }
+
+int ia4[2] = { (std::nullptr_t)0 };      // { dg-error "cannot convert 'std::nullptr_t' to 'int'" }
+int ia5[2] = { (std::nullptr_t)0, 0 };   // { dg-error "cannot convert 'std::nullptr_t' to 'int'" }
+int ia6[] = { (std::nullptr_t)0, 0 };    // { dg-error "cannot convert 'std::nullptr_t' to 'int'" }
+
+
+const char ca1[2] = { nullptr, 0 };       // { dg-error "cannot convert 'std::nullptr_t' to 'const char'" }
+
+const char ca2[2] = { (char*)nullptr, 0 };// { dg-error "invalid conversion from 'char\\\*' to 'char'" }
+
+const char ca3[2] = { std::nullptr_t () };// { dg-error "cannot convert 'std::nullptr_t'" }

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2020-05-15 18:53 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-07 18:50 [PATCH] reject scalar array initialization with nullptr [PR94510] Martin Sebor
2020-04-07 19:50 ` Marek Polacek
2020-04-07 20:46   ` Martin Sebor
2020-04-07 21:36     ` Marek Polacek
2020-04-08 17:23       ` Martin Sebor
2020-04-09 19:03         ` Jason Merrill
2020-04-09 19:24           ` Martin Sebor
2020-04-09 19:32             ` Jason Merrill
2020-04-09 20:23               ` Martin Sebor
2020-04-10 14:52                 ` Jason Merrill
2020-04-12 21:49                   ` Martin Sebor
2020-04-14  2:43                     ` Jason Merrill
2020-04-15 17:30                       ` Martin Sebor
2020-04-15 19:35                         ` Patrick Palka
2020-05-15 18:53                           ` Patrick Palka
2020-04-17  6:19                         ` Jason Merrill
2020-04-17 21:18                           ` Martin Sebor
2020-04-21  9:43                             ` Bernhard Reutner-Fischer
2020-04-21 20:33                             ` Jason Merrill
2020-04-21 21:52                               ` Martin Sebor
2020-04-08 18:43 ` Jason Merrill
2020-04-08 20:42   ` Martin Sebor

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).