public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-coroutines] c++: Fix DMI with lambda 'this' capture [PR94205]
@ 2020-04-01 19:12 Iain D Sandoe
0 siblings, 0 replies; only message in thread
From: Iain D Sandoe @ 2020-04-01 19:12 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:76f09260b7eccd6c3cfa3dcf3c22897fe12a8065
commit 76f09260b7eccd6c3cfa3dcf3c22897fe12a8065
Author: Jason Merrill <jason@redhat.com>
Date: Tue Mar 31 17:34:47 2020 -0400
c++: Fix DMI with lambda 'this' capture [PR94205]
We represent 'this' in a default member initializer with a PLACEHOLDER_EXPR.
Normally in constexpr evaluation when we encounter one it refers to
ctx->ctor, but when we're creating a temporary of class type, that replaces
ctx->ctor, so a PLACEHOLDER_EXPR that refers to the type of the member being
initialized needs to be replaced before that happens.
gcc/cp/ChangeLog
2020-03-31 Jason Merrill <jason@redhat.com>
PR c++/94205
* constexpr.c (cxx_eval_constant_expression) [TARGET_EXPR]: Call
replace_placeholders.
* typeck2.c (store_init_value): Fix arguments to
fold_non_dependent_expr.
Diff:
---
gcc/cp/ChangeLog | 8 ++++++++
gcc/cp/constexpr.c | 6 ++++++
gcc/cp/tree.c | 2 +-
gcc/cp/typeck2.c | 2 +-
gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi2.C | 20 ++++++++++++++++++++
gcc/testsuite/g++.dg/cpp1z/lambda-this4.C | 13 +++++++++++++
6 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2814a866f5d..3b522e8278c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2020-03-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/94205
+ * constexpr.c (cxx_eval_constant_expression) [TARGET_EXPR]: Call
+ replace_placeholders.
+ * typeck2.c (store_init_value): Fix arguments to
+ fold_non_dependent_expr.
+
2020-03-31 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_constant_expression) [TARGET_EXPR]: Use
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index e85b3c113f0..91f0c3ba269 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5553,6 +5553,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
tree init = TARGET_EXPR_INITIAL (t);
if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
{
+ if (ctx->object)
+ /* If the initializer contains any PLACEHOLDER_EXPR, we need to
+ resolve them before we create a new CONSTRUCTOR for the
+ temporary. */
+ init = replace_placeholders (init, ctx->object);
+
/* We're being expanded without an explicit target, so start
initializing a new object; expansion with an explicit target
strips the TARGET_EXPR before we get here. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a2172dea0d8..5eb0dcd717a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3239,7 +3239,7 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
a PLACEHOLDER_EXPR has been encountered. */
tree
-replace_placeholders (tree exp, tree obj, bool *seen_p)
+replace_placeholders (tree exp, tree obj, bool *seen_p /*= NULL*/)
{
/* This is only relevant for C++14. */
if (cxx_dialect < cxx14)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index bff4ddbcf81..cf1cb5ace66 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -871,7 +871,7 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
{
bool const_init;
tree oldval = value;
- value = fold_non_dependent_expr (value);
+ value = fold_non_dependent_expr (value, tf_warning_or_error, true, decl);
if (DECL_DECLARED_CONSTEXPR_P (decl)
|| (DECL_IN_AGGR_P (decl)
&& DECL_INITIALIZED_IN_CLASS_P (decl)))
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi2.C
new file mode 100644
index 00000000000..c51f734a134
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-nsdmi2.C
@@ -0,0 +1,20 @@
+// PR c++/94205
+// { dg-do compile { target c++14 } }
+
+struct S
+{
+ struct A
+ {
+ S *p;
+ constexpr A(S* p): p(p) {}
+ constexpr operator int() { p->i = 5; return 6; }
+ };
+ int i;
+ int a = A(this);
+};
+
+
+constexpr S s = {};
+
+#define SA(X) static_assert((X),#X)
+SA(s.i == 5 && s.a == 6);
diff --git a/gcc/testsuite/g++.dg/cpp1z/lambda-this4.C b/gcc/testsuite/g++.dg/cpp1z/lambda-this4.C
new file mode 100644
index 00000000000..5d968791491
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/lambda-this4.C
@@ -0,0 +1,13 @@
+// PR c++/94205
+// { dg-do compile { target c++17 } }
+
+struct S
+{
+ int i;
+ int a = [this] { this->i = 5; return 6; } ();
+};
+
+
+constexpr S s = {};
+
+static_assert (s.i == 5 && s.a == 6);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-04-01 19:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-01 19:12 [gcc/devel/c++-coroutines] c++: Fix DMI with lambda 'this' capture [PR94205] 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).