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.
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 (...) {
+  }
+}

Reply via email to