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.
This commit is contained in:
parent
8fda2c274a
commit
87fbd5347b
@ -1,3 +1,9 @@
|
||||
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
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
|
46
gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C
Normal file
46
gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C
Normal file
@ -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" }
|
||||
}
|
@ -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);
|
||||
|
||||
[&]() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user