This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to fix ICE in replace_placeholders_r (PR c++/79937)


In this testcase we have
C c = bar (X{1});
which store_init_value sees as
c = TARGET_EXPR <D.2332, bar (TARGET_EXPR <D.2298, {.i=1, .n=(&<PLACEHOLDER_EXPR struct X>)->i}>)>
i.e. we're initializing "c" with a TARGET_EXPR.  We call replace_placeholders
that walks the whole tree to substitute the placeholders.  Eventually we find
the nested <PLACEHOLDER_EXPR struct X> but that's for another object, so we
crash.  Seems that we shouldn't have stepped into the second TARGET_EXPR at
all; it has nothing to with "c", it's bar's argument.

It occurred to me that we shouldn't step into CALL_EXPRs and leave the
placeholders in function arguments to cp_gimplify_init_expr which calls
replace_placeholders for constructors.  Not sure if it's enough to handle
CALL_EXPRs like this, anything else?

Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?

2017-03-07  Marek Polacek  <polacek@redhat.com>

	PR c++/79937 - ICE in replace_placeholders_r
	* tree.c (replace_placeholders_r): Don't walk into CALL_EXPRs.

	* g++.dg/cpp1y/nsdmi-aggr7.C: New test.

diff --git gcc/cp/tree.c gcc/cp/tree.c
index d3c63b8..6a4f065 100644
--- gcc/cp/tree.c
+++ gcc/cp/tree.c
@@ -2751,6 +2751,11 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
 
   switch (TREE_CODE (*t))
     {
+    case CALL_EXPR:
+      /* Don't mess with placeholders in an unrelated object.  */
+      *walk_subtrees = false;
+      break;
+
     case PLACEHOLDER_EXPR:
       {
 	tree x = obj;
diff --git gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C
index e69de29..c2fd404 100644
--- gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C
+++ gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C
@@ -0,0 +1,21 @@
+// PR c++/79937
+// { dg-do compile { target c++14 } }
+
+struct C {};
+
+struct X {
+  unsigned i;
+  unsigned n = i;
+};
+
+C
+bar (X)
+{
+  return {};
+}
+
+void
+foo ()
+{
+  C c = bar (X{1});
+}

	Marek


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]