diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 543f4d9a4d9..7ad7737d582 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-01-15 Jason Merrill + + PR c++/63283 + * constexpr.c (potential_constant_expression_1): Handle reference + args in templates. + 2015-01-15 Thomas Schwinge James Norris Cesar Philippidis diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 14325069531..e27a892a51d 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3881,7 +3881,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, for (; i < nargs; ++i) { tree x = get_nth_callarg (t, i); - if (!RECUR (x, rval)) + /* In a template, reference arguments haven't been converted to + REFERENCE_TYPE and we might not even know if the parameter + is a reference, so accept lvalue constants too. */ + bool rv = processing_template_decl ? any : rval; + if (!RECUR (x, rv)) return false; } return true; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-template8.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-template8.C new file mode 100644 index 00000000000..7b2b9c7555b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-template8.C @@ -0,0 +1,10 @@ +// PR c++/63283 +// { dg-do compile { target c++11 } } + +constexpr int array_length(int (&array)[3]) { return 3; } +int a[] = { 1, 2, 3 }; +template int f() { + struct { int e[array_length(a)]; } t; + return sizeof(t); +} +int main() { f(); } diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert10.C b/gcc/testsuite/g++.dg/cpp0x/static_assert10.C index 216f2595b6b..e7f728e3f4f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/static_assert10.C +++ b/gcc/testsuite/g++.dg/cpp0x/static_assert10.C @@ -4,5 +4,5 @@ template bool foo(T) { int i; - static_assert(foo(i), "Error"); // { dg-error "non-constant condition|not usable" } + static_assert(foo(i), "Error"); // { dg-error "non-constant condition|not usable|non-constexpr" } }