diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-03 16:03:45 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-03 17:52:17 -0500 |
commit | 87fbd5347b33883006dc77e779b9edc590fcd2f0 (patch) | |
tree | 348baf29ff78fbda5e5cbdf5556c0aeebb6509d6 /gcc | |
parent | 8fda2c274ac66d60c1dfc1349e9efb4e8c2a3580 (diff) | |
download | gcc-87fbd5347b33883006dc77e779b9edc590fcd2f0.zip gcc-87fbd5347b33883006dc77e779b9edc590fcd2f0.tar.gz gcc-87fbd5347b33883006dc77e779b9edc590fcd2f0.tar.bz2 |
c++: Fix constexpr vs. reference parameter.
[expr.const] specifically rules out mentioning a reference even if its
address is never used, because it implies indirection that is similarly
non-constant for a pointer variable.
PR c++/66477
* constexpr.c (cxx_eval_constant_expression) [PARM_DECL]: Don't
defer loading the value of a reference.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr6.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C | 46 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-generic-const10.C | 2 |
5 files changed, 54 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a8af79c..8b35213 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2020-02-03 Jason Merrill <jason@redhat.com> + PR c++/66477 + * constexpr.c (cxx_eval_constant_expression) [PARM_DECL]: Don't + defer loading the value of a reference. + +2020-02-03 Jason Merrill <jason@redhat.com> + PR c++/91953 * constexpr.c (potential_constant_expression_1) [PARM_DECL]: Allow empty class type. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index a39ba41..3962763 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5322,8 +5322,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = *p; else if (lval) /* Defer in case this is only used for its type. */; - else if (TYPE_REF_P (TREE_TYPE (t))) - /* Defer, there's no lvalue->rvalue conversion. */; else if (COMPLETE_TYPE_P (TREE_TYPE (t)) && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false)) { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr6.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr6.C index 3a48398..1c06512 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr6.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr6.C @@ -12,7 +12,7 @@ constexpr auto sz_d = size(array_double); static_assert(sz_d == 3, "Array size failure"); void f(bool (¶m)[2]) { - static_assert(size(param) == 2, "Array size failure"); // Line 13 + static_assert(size(param) == 2, "Array size failure"); // { dg-error "" } short data[] = {-1, 2, -45, 6, 88, 99, -345}; static_assert(size(data) == 7, "Array size failure"); } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C new file mode 100644 index 0000000..7c3ce66 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C @@ -0,0 +1,46 @@ +// PR c++/66477 +// { dg-do compile { target c++11 } } + +struct a { constexpr bool g() const { return true; } }; +constexpr bool g(a&) { return true;} +constexpr bool h(a) { return true;} + +a a1; +a& ar = a1; + +void f(a ap, a& arp) +{ + a a2; + a& ar2 = a2; + + // Most of these are OK because no data is actually loaded. + static_assert (a1.g(),""); + static_assert (g(a1),""); + static_assert (h(a1),""); + + static_assert (a2.g(),""); + static_assert (g(a2),""); + static_assert (h(a2),""); + + static_assert (ap.g(),""); + static_assert (g(ap),""); + static_assert (h(ap),""); + + static_assert (ar.g(),""); + static_assert (g(ar),""); + static_assert (h(ar),""); + + // But these are specifically prohibited in [expr.const]/4.12: + // * an id-expression that refers to a variable or data member of reference + // type unless the reference has a preceding initialization and either + // ** it is usable in constant expressions or + // ** its lifetime began within the evaluation of e; + + static_assert (ar2.g(),""); // { dg-error "constant" } + static_assert (g(ar2),""); // { dg-error "constant" } + static_assert (h(ar2),""); // { dg-error "constant" } + + static_assert (arp.g(),""); // { dg-error "constant" } + static_assert (g(arp),""); // { dg-error "constant" } + static_assert (h(arp),""); // { dg-error "constant" } +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const10.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const10.C index e0080b3..2f48dae 100644 --- a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const10.C +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const10.C @@ -11,7 +11,7 @@ int main() constexpr auto x = f(); //ok, call constexpr const non-static method [](auto const &f) { - constexpr auto x = f(); /*ok*/ + constexpr auto x = f(); // { dg-error "" } }(f); [&]() { |