From c3c29ba5882f0f7db60ac2efca272a79cefa81c8 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 15 Jan 2015 15:46:03 -0500 Subject: [PATCH] re PR c++/63283 (constexpr function called by templated function is not treated as constexpr) PR c++/63283 * constexpr.c (potential_constant_expression_1): Handle reference args in templates. From-SVN: r219686 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/constexpr.c | 6 +++++- gcc/testsuite/g++.dg/cpp0x/constexpr-template8.C | 10 ++++++++++ gcc/testsuite/g++.dg/cpp0x/static_assert10.C | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-template8.C 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" } }