Jason Merrill <ja...@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 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 -- Dodji