re PR lto/87089 (tree check: expected class 'type', have 'declaration' (namespace_dec...
authorJan Hubicka <hubicka@ucw.cz>
Tue, 19 Mar 2019 14:53:43 +0000 (15:53 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 19 Mar 2019 14:53:43 +0000 (14:53 +0000)
PR lto/87809
PR lto/89335
* tree.c (free_lang_data_in_decl): Do not free context of C++
destrutors.

* g++.dg/lto/pr87089_0.C: New testcase.
* g++.dg/lto/pr87089_1.C: New testcase.
* g++.dg/lto/pr89335_0.C: New testcase.

From-SVN: r269799

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/pr87089_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/pr87089_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/pr89335_0.C [new file with mode: 0644]
gcc/tree.c

index 9327ed8..bb62711 100644 (file)
@@ -1,3 +1,10 @@
+2019-03-19  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR lto/87809
+       PR lto/89335
+       * tree.c (free_lang_data_in_decl): Do not free context of C++
+       destrutors.
+
 2019-03-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/89506
index 1b5cfeb..986457a 100644 (file)
@@ -1,3 +1,11 @@
+2019-03-19  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR lto/87809
+       PR lto/89335
+       * g++.dg/lto/pr87089_0.C: New testcase.
+       * g++.dg/lto/pr87089_1.C: New testcase.
+       * g++.dg/lto/pr89335_0.C: New testcase.
+
 2019-03-19  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        PR target/89736
diff --git a/gcc/testsuite/g++.dg/lto/pr87089_0.C b/gcc/testsuite/g++.dg/lto/pr87089_0.C
new file mode 100644 (file)
index 0000000..7644534
--- /dev/null
@@ -0,0 +1,21 @@
+// { dg-lto-do link }
+// { dg-extra-ld-options "-r -nostdlib -flinker-output=nolto-rel" }
+namespace itpp {
+template <class a> void b(a *c) { c[0].~a(); }
+class CFix;
+template <class> class d {
+  void e(const char *);
+  CFix *data;
+};
+class CFix {
+public:
+  virtual ~CFix();
+};
+template <> void d<int>::e(const char *) { b(data); }
+} // namespace itpp
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lto/pr87089_1.C b/gcc/testsuite/g++.dg/lto/pr87089_1.C
new file mode 100644 (file)
index 0000000..0c243c2
--- /dev/null
@@ -0,0 +1,12 @@
+namespace itpp {
+enum a { b };
+class CFix {
+public:
+  virtual ~CFix();
+};
+template <a = b> class c : CFix {
+  ~c() {}
+};
+template class c<>;
+} // namespace itpp
+
diff --git a/gcc/testsuite/g++.dg/lto/pr89335_0.C b/gcc/testsuite/g++.dg/lto/pr89335_0.C
new file mode 100644 (file)
index 0000000..df2d2ba
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-lto-do link }
+// { dg-lto-options {{-O2 -flto -Wsuggest-final-methods}} }
+// { dg-extra-ld-options "-r -nostdlib -flinker-output=nolto-rel" }
+class Container
+{
+public:
+  virtual ~Container ();
+};
+class List : public Container // { dg-lto-message "final would enable devirtualization" }
+{
+};
+static List cache[256];
+int main (void)
+{
+  return 0;
+}
index d061a04..8ea4251 100644 (file)
@@ -5772,10 +5772,16 @@ free_lang_data_in_decl (tree decl, struct free_lang_data_d *fld)
      not do well with TREE_CHAIN pointers linking them.
 
      Also do not drop containing types for virtual methods and tables because
-     these are needed by devirtualization.  */
+     these are needed by devirtualization.
+     C++ destructors are special because C++ frontends sometimes produces
+     virtual destructor as an alias of non-virtual destructor.  In
+     devirutalization code we always walk through aliases and we need
+     context to be preserved too.  See PR89335  */
   if (TREE_CODE (decl) != FIELD_DECL
       && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
-          || !DECL_VIRTUAL_P (decl)))
+          || (!DECL_VIRTUAL_P (decl)
+             && (TREE_CODE (decl) != FUNCTION_DECL
+                 || !DECL_CXX_DESTRUCTOR_P (decl)))))
     DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl));
 }