public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/47705 (ICE with non-pointer argument to pointer template parameter)
@ 2011-03-08 17:25 Jason Merrill
  2011-03-08 21:40 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2011-03-08 17:25 UTC (permalink / raw)
  To: gcc-patches List

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

We were asserting that any argument to a non-type template parameter of 
pointer type must be an address.  Which is true of valid code (apart 
from null pointer values), but not necessarily of invalid code, where we 
should complain rather than crash.

Tested x86_64-pc-linux-gnu, applied to trunk.

[-- Attachment #2: 47705.patch --]
[-- Type: text/plain, Size: 1891 bytes --]

commit 0aa8b389e5b3d863edd4e9969cadf2af5f2c1907
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 8 11:02:49 2011 -0500

    	PR c++/47705
    	* pt.c (convert_nontype_argument): Don't crash on non-pointer
    	argument to pointer parameter.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 48f9382..cda9df8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5369,15 +5369,20 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
 	 qualification conversion. Let's strip everything.  */
       else if (TYPE_PTROBV_P (type))
 	{
-	  STRIP_NOPS (expr);
-	  gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
-	  gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE);
-	  /* Skip the ADDR_EXPR only if it is part of the decay for
-	     an array. Otherwise, it is part of the original argument
-	     in the source code.  */
-	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE)
-	    expr = TREE_OPERAND (expr, 0);
-	  expr_type = TREE_TYPE (expr);
+	  tree sub = expr;
+	  STRIP_NOPS (sub);
+	  if (TREE_CODE (sub) == ADDR_EXPR)
+	    {
+	      gcc_assert (TREE_CODE (TREE_TYPE (sub)) == POINTER_TYPE);
+	      /* Skip the ADDR_EXPR only if it is part of the decay for
+		 an array. Otherwise, it is part of the original argument
+		 in the source code.  */
+	      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (sub, 0))) == ARRAY_TYPE)
+		expr = TREE_OPERAND (sub, 0);
+	      else
+		expr = sub;
+	      expr_type = TREE_TYPE (expr);
+	    }
 	}
     }
 
diff --git a/gcc/testsuite/g++.dg/template/nontype21.C b/gcc/testsuite/g++.dg/template/nontype21.C
new file mode 100644
index 0000000..c8e73d2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/nontype21.C
@@ -0,0 +1,10 @@
+// PR c++/47705
+
+template<char const * const x> class Something {
+};
+
+extern char const xyz;
+
+class SomethingElse:public Something<xyz> { // { dg-error "const char *" }
+};
+

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

* Re: C++ PATCH for c++/47705 (ICE with non-pointer argument to pointer template parameter)
  2011-03-08 17:25 C++ PATCH for c++/47705 (ICE with non-pointer argument to pointer template parameter) Jason Merrill
@ 2011-03-08 21:40 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2011-03-08 21:40 UTC (permalink / raw)
  To: gcc-patches List; +Cc: Dodji Seketeli

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

On 03/08/2011 12:25 PM, Jason Merrill wrote:
> We were asserting that any argument to a non-type template parameter of
> pointer type must be an address. Which is true of valid code (apart from
> null pointer values), but not necessarily of invalid code, where we
> should complain rather than crash.

Dodji had an idea for a different way to fix this crash: avoid the call 
to decay_conversion which adds the NOP to convert 'const int' to 'int' 
by limiting it to the case where the argument is an array.  I think I 
like this way better.

Tested x86_64-pc-linux-gnu, applied to trunk.

[-- Attachment #2: 47705-dodji.patch --]
[-- Type: text/plain, Size: 2353 bytes --]

commit c9e36778318c240777889a403693e95488a13b6d
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 8 14:02:21 2011 -0500

    	PR c++/47705
    	* pt.c (convert_nontype_argument): Only call decay_conversion on
    	arrays.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cda9df8..2ca2cd0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5314,7 +5314,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
 
   /* Add the ADDR_EXPR now for the benefit of
      value_dependent_expression_p.  */
-  if (TYPE_PTROBV_P (type))
+  if (TYPE_PTROBV_P (type)
+      && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE)
     expr = decay_conversion (expr);
 
   /* If we are in a template, EXPR may be non-dependent, but still
@@ -5369,20 +5370,15 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
 	 qualification conversion. Let's strip everything.  */
       else if (TYPE_PTROBV_P (type))
 	{
-	  tree sub = expr;
-	  STRIP_NOPS (sub);
-	  if (TREE_CODE (sub) == ADDR_EXPR)
-	    {
-	      gcc_assert (TREE_CODE (TREE_TYPE (sub)) == POINTER_TYPE);
-	      /* Skip the ADDR_EXPR only if it is part of the decay for
-		 an array. Otherwise, it is part of the original argument
-		 in the source code.  */
-	      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (sub, 0))) == ARRAY_TYPE)
-		expr = TREE_OPERAND (sub, 0);
-	      else
-		expr = sub;
-	      expr_type = TREE_TYPE (expr);
-	    }
+	  STRIP_NOPS (expr);
+	  gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
+	  gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE);
+	  /* Skip the ADDR_EXPR only if it is part of the decay for
+	     an array. Otherwise, it is part of the original argument
+	     in the source code.  */
+	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE)
+	    expr = TREE_OPERAND (expr, 0);
+	  expr_type = TREE_TYPE (expr);
 	}
     }
 
diff --git a/gcc/testsuite/g++.dg/template/nontype21.C b/gcc/testsuite/g++.dg/template/nontype21.C
index c0f5319..69cab54 100644
--- a/gcc/testsuite/g++.dg/template/nontype21.C
+++ b/gcc/testsuite/g++.dg/template/nontype21.C
@@ -4,4 +4,4 @@ template<char const * const x> class Something { };
 
 extern char const xyz;
 
-class SomethingElse:public Something<xyz> { }; // { dg-error "const char *" }
+class SomethingElse:public Something<xyz> { }; // { dg-error "xyz. is a variable" }

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

end of thread, other threads:[~2011-03-08 21:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-08 17:25 C++ PATCH for c++/47705 (ICE with non-pointer argument to pointer template parameter) Jason Merrill
2011-03-08 21:40 ` Jason Merrill

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