This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/47705 (ICE with non-pointer argument to pointer template parameter)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Cc: Dodji Seketeli <dodji at redhat dot com>
- Date: Tue, 08 Mar 2011 16:40:07 -0500
- Subject: Re: C++ PATCH for c++/47705 (ICE with non-pointer argument to pointer template parameter)
- References: <4D766697.2020507@redhat.com>
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.
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" }