public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-coroutines] c++: Fix constexpr vs. reference parameter.
@ 2020-02-04 20:56 Iain D Sandoe
0 siblings, 0 replies; only message in thread
From: Iain D Sandoe @ 2020-02-04 20:56 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:87fbd5347b33883006dc77e779b9edc590fcd2f0
commit 87fbd5347b33883006dc77e779b9edc590fcd2f0
Author: Jason Merrill <jason@redhat.com>
Date: Mon Feb 3 16:03:45 2020 -0500
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.
Diff:
---
gcc/cp/ChangeLog | 6 +++
gcc/cp/constexpr.c | 2 -
gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr6.C | 2 +-
gcc/testsuite/g++.dg/cpp0x/constexpr-ref12.C | 46 ++++++++++++++++++++++
.../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..2f48dae4 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);
[&]() {
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-02-04 20:56 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-04 20:56 [gcc/devel/c++-coroutines] c++: Fix constexpr vs. reference parameter Iain D Sandoe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).