public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Fix ICE with nsdmi [PR99705]
@ 2021-03-23  9:57 Jakub Jelinek
  2021-03-23 20:51 ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2021-03-23  9:57 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 4107 bytes --]

Hi!

When adding P0784R7 constexpr new support, we still didn't have
P1331R2 implemented and so I had to change also build_vec_delete_1
- instead of having uninitialized tbase temporary later initialized
by MODIFY_EXPR I've set the DECL_INITIAL for it - because otherwise
it would be rejected during constexpr evaluation which didn't like
uninitialized vars.  Unfortunately, that change broke the following
testcase.
The problem is that these temporaries (not just tbase but tbase was
the only one with an initializer) are created during NSDMI parsing
and current_function_decl is NULL at that point.  Later when we
clone body of constructors, auto_var_in_fn_p is false for those
(as they have NULL DECL_CONTEXT) and so they aren't duplicated,
and what is worse, the DECL_INITIAL isn't duplicated either nor processed,
and during expansion we ICE because the code from DECL_INITIAL of that
var refers to the abstract constructor's PARM_DECL (this) rather than
the actual constructor's one.

So, either we can just revert those build_vec_delete_1 changes (as done
in the second patch - in attachment), or, as the first patch does, we can
copy the temporaries during bot_manip like we copy the temporaries of
TARGET_EXPRs.  To me that looks like a better fix because e.g. if
break_out_of_target_exprs is called for the same NSDMI multiple times,
sharing the temporaries looks just wrong to me.  If the temporaries
are declared as BIND_EXPR_VARS of some BIND_EXPR (which is the case
of the tbase variable built by build_vec_delete_1 and is the only way
how the DECL_INITIAL can be walked by *walk_tree*), then we need to
copy it also in the BIND_EXPR BIND_EXPR_VARS chain, other temporaries
(those that don't need DECL_INITIAL) often have just DECL_EXPR and no
corresponding BIND_EXPR.
Note, ({ }) are rejected in nsdmis, so all we run into are temporaries
the FE creates artificially.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or do you prefer the patch in attachment (or something else)?

2021-03-23  Jakub Jelinek  <jakub@redhat.com>

	PR c++/99705
	* tree.c (bot_manip): Remap artificial automatic temporaries with
	NULL DECL_CONTEXT mentioned in DECL_EXPR or in BIND_EXPR_VARS.

	* g++.dg/cpp0x/new5.C: New test.

--- gcc/cp/tree.c.jj	2021-03-18 09:49:22.112712307 +0100
+++ gcc/cp/tree.c	2021-03-23 00:08:35.901724895 +0100
@@ -3128,6 +3128,35 @@ bot_manip (tree* tp, int* walk_subtrees,
 	}
       return NULL_TREE;
     }
+  if (TREE_CODE (*tp) == DECL_EXPR
+      && VAR_P (DECL_EXPR_DECL (*tp))
+      && DECL_ARTIFICIAL (DECL_EXPR_DECL (*tp))
+      && !TREE_STATIC (DECL_EXPR_DECL (*tp))
+      && DECL_CONTEXT (DECL_EXPR_DECL (*tp)) == NULL_TREE
+      && !splay_tree_lookup (target_remap,
+			     (splay_tree_key) DECL_EXPR_DECL (*tp)))
+    {
+      tree t = create_temporary_var (TREE_TYPE (DECL_EXPR_DECL (*tp)));
+      splay_tree_insert (target_remap, (splay_tree_key) DECL_EXPR_DECL (*tp),
+			 (splay_tree_value) t);
+    }
+  if (TREE_CODE (*tp) == BIND_EXPR && BIND_EXPR_VARS (*tp))
+    {
+      copy_tree_r (tp, walk_subtrees, NULL);
+      for (tree *p = &BIND_EXPR_VARS (*tp); *p; p = &DECL_CHAIN (*p))
+	{
+	  gcc_assert (VAR_P (*p) && DECL_ARTIFICIAL (*p) && !TREE_STATIC (*p));
+	  tree t = create_temporary_var (TREE_TYPE (*p));
+	  DECL_INITIAL (t) = DECL_INITIAL (*p);
+	  DECL_CHAIN (t) = DECL_CHAIN (*p);
+	  splay_tree_insert (target_remap, (splay_tree_key) *p,
+			     (splay_tree_value) t);
+	  *p = t;
+	}
+      if (data.clear_location && EXPR_HAS_LOCATION (*tp))
+	SET_EXPR_LOCATION (*tp, input_location);
+      return NULL_TREE;
+    }
 
   /* Make a copy of this node.  */
   t = copy_tree_r (tp, walk_subtrees, NULL);
--- gcc/testsuite/g++.dg/cpp0x/new5.C.jj	2021-03-22 14:08:29.168782588 +0100
+++ gcc/testsuite/g++.dg/cpp0x/new5.C	2021-03-22 14:07:35.253378808 +0100
@@ -0,0 +1,21 @@
+// PR c++/99705
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct C
+{
+  C () { f (); }
+  ~C () {}
+  static void f () {}
+};
+
+struct X
+{
+  X ();
+  int n = 10;
+  C<int> *p = new C<int>[n];
+};
+
+X::X ()
+{
+}

	Jakub

[-- Attachment #2: S875a --]
[-- Type: text/plain, Size: 1380 bytes --]

2021-03-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/99705
	* init.c (build_vec_delete_1): Revert to using a MODIFY_EXPR for tbase
	initialization instead of DECL_INITIAL.

	* g++.dg/cpp0x/new5.C: New test.

--- gcc/cp/init.c.jj	2021-03-22 13:25:30.153349516 +0100
+++ gcc/cp/init.c	2021-03-22 13:35:34.206653080 +0100
@@ -3903,10 +3903,13 @@ build_vec_delete_1 (location_t loc, tree
 			     fold_convert (sizetype, maxindex));
 
   tbase = create_temporary_var (ptype);
-  DECL_INITIAL (tbase)
+  tbase_init
     = fold_build_pointer_plus_loc (loc, fold_convert (ptype, base),
 				   virtual_size);
-  tbase_init = build_stmt (loc, DECL_EXPR, tbase);
+  tbase_init = cp_build_modify_expr (loc, tbase, NOP_EXPR, tbase_init,
+				     complain);
+  tbase_init = build_compound_expr (loc, build_stmt (loc, DECL_EXPR, tbase),
+				    tbase_init);
   controller = build3 (BIND_EXPR, void_type_node, tbase, NULL_TREE, NULL_TREE);
   TREE_SIDE_EFFECTS (controller) = 1;
 
--- gcc/testsuite/g++.dg/cpp0x/new5.C.jj	2021-03-22 14:08:29.168782588 +0100
+++ gcc/testsuite/g++.dg/cpp0x/new5.C	2021-03-22 14:07:35.253378808 +0100
@@ -0,0 +1,21 @@
+// PR c++/99705
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct C
+{
+  C () { f (); }
+  ~C () {}
+  static void f () {}
+};
+
+struct X
+{
+  X ();
+  int n = 10;
+  C<int> *p = new C<int>[n];
+};
+
+X::X ()
+{
+}

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-03-25 20:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-23  9:57 [PATCH] c++: Fix ICE with nsdmi [PR99705] Jakub Jelinek
2021-03-23 20:51 ` Jason Merrill
2021-03-23 20:59   ` Jakub Jelinek
2021-03-25 10:50   ` [PATCH] c++, v2: " Jakub Jelinek
2021-03-25 20:20     ` Jason Merrill
2021-03-25 20:33       ` Jakub Jelinek
2021-03-25 20:36         ` Jason Merrill

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).