diff mbox series

Fix ICE in copy_function_or_variable

Message ID 20190102152457.aiilwu3l6lial6po@kam.mff.cuni.cz
State New
Headers show
Series Fix ICE in copy_function_or_variable | expand

Commit Message

Jan Hubicka Jan. 2, 2019, 3:24 p.m. UTC
Hi,
this patch fixes ICE when at WPA we try to look for ctor which was
removed at compilation time and thus not streamed.  While testcase seems
to reproduce only on gcc 9, this is old bug and thus the fix should be
backported to gcc 8 and 7 after some additional testing.

Bootstrapped/regtested x86_64-linux, comitted.

	PR lto/88130
	* varpool.c (varpool_node::ctor_useable_for_folding_p): Also return
	false at WPA time when body was removed.
	* g++.dg/torture/pr88130.C: New testcase.
diff mbox series

Patch

Index: varpool.c
===================================================================
--- varpool.c	(revision 267499)
+++ varpool.c	(working copy)
@@ -335,16 +335,16 @@  varpool_node::ctor_useable_for_folding_p
   if (TREE_THIS_VOLATILE (decl))
     return false;
 
+  /* Avoid attempts to load constructors that was not streamed.  */
+  if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
+      && real_node->body_removed)
+    return false;
+
   /* If we do not have a constructor, we can't use it.  */
   if (DECL_INITIAL (real_node->decl) == error_mark_node
       && !real_node->lto_file_data)
     return false;
 
-  /* Avoid attempts to load constructors that was not streamed.  */
-  if (flag_ltrans && DECL_INITIAL (real_node->decl) == error_mark_node
-      && real_node->body_removed)
-    return false;
-
   /* Vtables are defined by their types and must match no matter of interposition
      rules.  */
   if (DECL_VIRTUAL_P (decl))
Index: testsuite/g++.dg/torture/pr88130.C
===================================================================
--- testsuite/g++.dg/torture/pr88130.C	(nonexistent)
+++ testsuite/g++.dg/torture/pr88130.C	(working copy)
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-flto" } */
+/* { dg-require-effective-target lto } */
+class a {
+public:
+  static const long b = 1;
+};
+struct c {
+  enum d { e };
+};
+class C;
+class f {
+public:
+  f(c::d);
+  template <typename g> C operator<=(g);
+};
+class C {
+public:
+  template <typename h> void operator!=(h &);
+};
+void i() {
+  f j(c::e);
+  try {
+    j <= 0 != a::b;
+  } catch (...) {
+  }
+}