diff mbox series

[C++] Fix -fsyntax-only (PR c++/89403)

Message ID 20190220223820.GR2135@tucnak
State New
Headers show
Series [C++] Fix -fsyntax-only (PR c++/89403) | expand

Commit Message

Jakub Jelinek Feb. 20, 2019, 10:38 p.m. UTC
Hi!

On the following testcase we ICE, because expand_or_defer_fn is called
multiple times on the same ctor (once from instantiation of constexpr
functions, once from c_parse_final_cleanups) and this calls maybe_clone_body
which isn't really prepared to be called multiple times.  In particular,
when the clones already have DECL_INITIAL etc., calling
start_preparsed_function on it again doesn't set cfun to non-NULL and the
code wants to store something there (but generally, it is pointless to do it
again even if it worked).  If maybe_clone_body returns true, we set
TREE_ASM_WRITTEN:
  if (maybe_clone_body (fn))
    {
      /* We don't want to process FN again, so pretend we've written
         it out, even though we haven't.  */
      TREE_ASM_WRITTEN (fn) = 1;
      /* If this is a constexpr function, keep DECL_SAVED_TREE.  */
      if (!DECL_DECLARED_CONSTEXPR_P (fn))
        DECL_SAVED_TREE (fn) = NULL_TREE;
      return false;
    }
but if it doesn't because it wants to emit the original ctor as well (can't
use aliases), then we don't set that.  This patch moves the -fsyntax-only
setting of the TREE_ASM_WRITTEN bit from c_parse_final_cleanups to
expand_or_defer_fn_1, so that if we do it once, we don't do that again.
For -fsyntax-only, I believe there is nothing further we want to do on the
cdtor.

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

2019-02-20  Jakub Jelinek  <jakub@redhat.com>

	PR c++/89403
	* decl2.c (c_parse_final_cleanups): Move TREE_ASM_WRITTEN setting
	for flag_syntax_only from here...
	* semantics.c (expand_or_defer_fn_1): ... here.

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


	Jakub

Comments

Jason Merrill Feb. 21, 2019, midnight UTC | #1
On 2/20/19 12:38 PM, Jakub Jelinek wrote:
> Hi!
> 
> On the following testcase we ICE, because expand_or_defer_fn is called
> multiple times on the same ctor (once from instantiation of constexpr
> functions, once from c_parse_final_cleanups) and this calls maybe_clone_body
> which isn't really prepared to be called multiple times.  In particular,
> when the clones already have DECL_INITIAL etc., calling
> start_preparsed_function on it again doesn't set cfun to non-NULL and the
> code wants to store something there (but generally, it is pointless to do it
> again even if it worked).  If maybe_clone_body returns true, we set
> TREE_ASM_WRITTEN:
>    if (maybe_clone_body (fn))
>      {
>        /* We don't want to process FN again, so pretend we've written
>           it out, even though we haven't.  */
>        TREE_ASM_WRITTEN (fn) = 1;
>        /* If this is a constexpr function, keep DECL_SAVED_TREE.  */
>        if (!DECL_DECLARED_CONSTEXPR_P (fn))
>          DECL_SAVED_TREE (fn) = NULL_TREE;
>        return false;
>      }
> but if it doesn't because it wants to emit the original ctor as well (can't
> use aliases), then we don't set that.  This patch moves the -fsyntax-only
> setting of the TREE_ASM_WRITTEN bit from c_parse_final_cleanups to
> expand_or_defer_fn_1, so that if we do it once, we don't do that again.
> For -fsyntax-only, I believe there is nothing further we want to do on the
> cdtor.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2019-02-20  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/89403
> 	* decl2.c (c_parse_final_cleanups): Move TREE_ASM_WRITTEN setting
> 	for flag_syntax_only from here...
> 	* semantics.c (expand_or_defer_fn_1): ... here.

OK.

Jason
diff mbox series

Patch

--- gcc/cp/decl2.c.jj	2019-01-25 23:46:07.045183165 +0100
+++ gcc/cp/decl2.c	2019-02-20 18:37:36.824869503 +0100
@@ -4965,11 +4965,6 @@  c_parse_final_cleanups (void)
 	      /* Generate RTL for this function now that we know we
 		 need it.  */
 	      expand_or_defer_fn (decl);
-	      /* If we're compiling -fsyntax-only pretend that this
-		 function has been written out so that we don't try to
-		 expand it again.  */
-	      if (flag_syntax_only)
-		TREE_ASM_WRITTEN (decl) = 1;
 	      reconsider = true;
 	    }
 	}
--- gcc/cp/semantics.c.jj	2019-02-18 20:48:37.667649895 +0100
+++ gcc/cp/semantics.c	2019-02-20 18:45:00.582682109 +0100
@@ -4352,7 +4352,12 @@  expand_or_defer_fn_1 (tree fn)
   /* There's no reason to do any of the work here if we're only doing
      semantic analysis; this code just generates RTL.  */
   if (flag_syntax_only)
-    return false;
+    {
+      /* Pretend that this function has been written out so that we don't try
+	 to expand it again.  */
+      TREE_ASM_WRITTEN (fn) = 1;
+      return false;
+    }
 
   return true;
 }
--- gcc/testsuite/g++.dg/cpp0x/pr89403.C.jj	2019-02-20 18:41:01.007535052 +0100
+++ gcc/testsuite/g++.dg/cpp0x/pr89403.C	2019-02-20 18:40:05.687424739 +0100
@@ -0,0 +1,18 @@ 
+// PR c++/89403
+// { dg-do compile { target c++11 } }
+// { dg-options "-Os -fsyntax-only" }
+
+template <typename T>
+struct A : T {
+  constexpr A() : T() { }
+};
+
+template <typename T>
+struct B {
+  A<T> b;
+  constexpr B() { }
+};
+
+struct C { struct {} s; };
+constexpr B<C> b{};
+constexpr C c = b.b;