diff mbox

PR c++/55311 - Cannot specialize alias template with arg of type array of char

Message ID 87mwx3fs1n.fsf@redhat.com
State New
Headers show

Commit Message

Dodji Seketeli Dec. 24, 2012, 2:23 p.m. UTC
Jason Merrill <jason@redhat.com> writes:

> On 12/22/2012 11:03 AM, Dodji Seketeli wrote:
>> [1]: The relacement of the VAR_DECL by its initializer is done by
>> decay_conversion by callig decl_constant_value_safe.  That replacement
>> doesn't happen if processing_template_decl is not set.  That's why it
>> doesn't happen for the class template instantiation at line 9, leading
>> to no error message there.
>
> This is the bug.  decay_conversion on an array should take the
> address, not return the initializer.

Right.  So would something like this be acceptable then?

gcc/cp/

	PR c++/55311
	* pt.c (decay_conversion): Do not return the initializer of an array.

gcc/testsuite/

	PR c++/55311
	* g++.dg/cpp0x/alias-decl-30.C: New test.
---
 gcc/cp/typeck.c                            | 20 +++++++++++++-------
 gcc/testsuite/g++.dg/cpp0x/alias-decl-30.C | 15 +++++++++++++++
 2 files changed, 28 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-30.C

Comments

Jason Merrill Dec. 26, 2012, 6:54 p.m. UTC | #1
On 12/24/2012 09:23 AM, Dodji Seketeli wrote:
> +  /* For and array decl decay_conversion should not try to return its

"an array..."

OK with that change.

Jason
diff mbox

Patch

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index ef76dcd..3fa913d 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1880,19 +1880,25 @@  decay_conversion (tree exp, tsubst_flags_t complain)
       return error_mark_node;
     }
 
-  /* FIXME remove? at least need to remember that this isn't really a
-     constant expression if EXP isn't decl_constant_var_p, like with
-     C_MAYBE_CONST_EXPR.  */
-  exp = decl_constant_value_safe (exp);
-  if (error_operand_p (exp))
-    return error_mark_node;
+  code = TREE_CODE (type);
+
+  /* For and array decl decay_conversion should not try to return its
+     initializer.  */
+  if (code != ARRAY_TYPE)
+    {
+      /* FIXME remove? at least need to remember that this isn't really a
+	 constant expression if EXP isn't decl_constant_var_p, like with
+	 C_MAYBE_CONST_EXPR.  */
+      exp = decl_constant_value_safe (exp);
+      if (error_operand_p (exp))
+	return error_mark_node;
+    }
 
   if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
     return nullptr_node;
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
-  code = TREE_CODE (type);
   if (code == VOID_TYPE)
     {
       if (complain & tf_error)
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-30.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-30.C
new file mode 100644
index 0000000..7ad5e6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-30.C
@@ -0,0 +1,15 @@ 
+// Origin PR c++/55311
+// { dg-do compile { target c++11 } }
+
+template <const char *const C, typename T>
+struct A
+{};
+
+struct B {};
+
+extern constexpr char HELLO_WORLD[] = "hello world";
+
+A<HELLO_WORLD, B> g; // <-- This works fine
+
+template <typename T>
+using PartiallySpecialized = A<HELLO_WORLD, T>;  // <-- This fails