Message ID | 1ab3a8e7-a6cb-3097-699b-f8807188e110@suse.cz |
---|---|
State | New |
Headers | show |
Series | Check for TYPE_NAME in type_with_linkage_p. | expand |
> Hi. > > This one another IPA devirt ICE fix where we can end up > with a local array that has not TYPE_NAME. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? > Thanks, > Martin > > gcc/ChangeLog: > > 2019-11-27 Martin Liska <mliska@suse.cz> > > PR lto/91574 > * ipa-devirt.c (types_same_for_odr): Check for existence > of TYPE_NAMEs. > > gcc/testsuite/ChangeLog: > > 2019-11-27 Martin Liska <mliska@suse.cz> > > PR lto/91574 > * g++.dg/lto/pr91574_0.C: New test. > --- > gcc/ipa-devirt.c | 9 +++++++-- > gcc/testsuite/g++.dg/lto/pr91574_0.C | 23 +++++++++++++++++++++++ > 2 files changed, 30 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/lto/pr91574_0.C > > > diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c > index c158d3c968d..72b5ee422e1 100644 > --- a/gcc/ipa-devirt.c > +++ b/gcc/ipa-devirt.c > @@ -356,8 +356,13 @@ types_same_for_odr (const_tree type1, const_tree type2) > || (type_with_linkage_p (type2) && type_in_anonymous_namespace_p (type2))) > return false; > > - return (DECL_ASSEMBLER_NAME (TYPE_NAME (type1)) > - == DECL_ASSEMBLER_NAME (TYPE_NAME (type2))); > + tree tn1 = TYPE_NAME (type1); > + tree tn2 = TYPE_NAME (type2); > + > + /* We may meet a locally defined ARRAY_TYPE which > + has not an assembler name. */ > + return (tn1 != NULL_TREE && tn2 != NULL_TREE > + && DECL_ASSEMBLER_NAME (tn1) == DECL_ASSEMBLER_NAME (tn2)); The usual way to check for type with ODR name is type_with_linkage_p which function already checks earlier. I think it would be clenaer to write it as: /* If both type has mangled defined check if they are same. Watch for anonymous types which are all mangled as "<anon">. */ if (!type_with_linkage_p (type1) || !type_with_linkage_p (type2)) return false; if (type_in_anonymous_namespace_p (type1) || type_in_anonymous_namespace_p (type2)) return false; return (DECL_ASSEMBLER_NAME (TYPE_NAME (type1)) == DECL_ASSEMBLER_NAME (TYPE_NAME (type2))); OK with this change and thanks a lot for looking into this. Honza
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index c158d3c968d..72b5ee422e1 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -356,8 +356,13 @@ types_same_for_odr (const_tree type1, const_tree type2) || (type_with_linkage_p (type2) && type_in_anonymous_namespace_p (type2))) return false; - return (DECL_ASSEMBLER_NAME (TYPE_NAME (type1)) - == DECL_ASSEMBLER_NAME (TYPE_NAME (type2))); + tree tn1 = TYPE_NAME (type1); + tree tn2 = TYPE_NAME (type2); + + /* We may meet a locally defined ARRAY_TYPE which + has not an assembler name. */ + return (tn1 != NULL_TREE && tn2 != NULL_TREE + && DECL_ASSEMBLER_NAME (tn1) == DECL_ASSEMBLER_NAME (tn2)); } /* Return true if we can decide on ODR equivalency. diff --git a/gcc/testsuite/g++.dg/lto/pr91574_0.C b/gcc/testsuite/g++.dg/lto/pr91574_0.C new file mode 100644 index 00000000000..346a8015c98 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr91574_0.C @@ -0,0 +1,23 @@ +// PR lto/91574 +// { dg-lto-do link } +// { dg-lto-options { { -fPIC -flto -O2 } } } +// { dg-require-effective-target shared } +// { dg-require-effective-target fpic } +// { dg-extra-ld-options "-shared" } + +class A +{ +public: + virtual ~A (); + A (A &); + virtual unsigned m_fn1 () const; +}; +class B : A +{ + unsigned m_fn1 () const; +}; +void +fn1 (B p1) +{ + B a[]{p1, p1}; +}