From 2ca6d1813e47d235bb5f001b1a99b19652ea408a Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 19 Mar 2019 15:53:43 +0100 Subject: [PATCH] re PR lto/87089 (tree check: expected class 'type', have 'declaration' (namespace_decl) in type_with_linkage_p, at ipa-utils.h) 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 | 7 +++++++ gcc/testsuite/ChangeLog | 8 ++++++++ gcc/testsuite/g++.dg/lto/pr87089_0.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.dg/lto/pr87089_1.C | 12 ++++++++++++ gcc/testsuite/g++.dg/lto/pr89335_0.C | 16 ++++++++++++++++ gcc/tree.c | 10 ++++++++-- 6 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lto/pr87089_0.C create mode 100644 gcc/testsuite/g++.dg/lto/pr87089_1.C create mode 100644 gcc/testsuite/g++.dg/lto/pr89335_0.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9327ed858db..bb627115a48 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-03-19 Jan Hubicka + + 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 PR target/89506 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b5cfebd921..986457ab159 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-03-19 Jan Hubicka + + 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 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 index 00000000000..764453472c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr87089_0.C @@ -0,0 +1,21 @@ +// { dg-lto-do link } +// { dg-extra-ld-options "-r -nostdlib -flinker-output=nolto-rel" } +namespace itpp { +template void b(a *c) { c[0].~a(); } +class CFix; +template class d { + void e(const char *); + CFix *data; +}; +class CFix { +public: + virtual ~CFix(); +}; +template <> void d::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 index 00000000000..0c243c24d97 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr87089_1.C @@ -0,0 +1,12 @@ +namespace itpp { +enum a { b }; +class CFix { +public: + virtual ~CFix(); +}; +template 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 index 00000000000..df2d2ba8fb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr89335_0.C @@ -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; +} diff --git a/gcc/tree.c b/gcc/tree.c index d061a0422ff..8ea42512aa7 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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)); } -- 2.30.2