Martin Liška <mli...@suse.cz> writes: > diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c > index a884a465a5d..e53461b1f5c 100644 > --- a/gcc/ipa-devirt.c > +++ b/gcc/ipa-devirt.c > @@ -1036,20 +1036,13 @@ warn_types_mismatch (tree t1, tree t2, location_t > loc1, location_t loc2) > /* If types have mangled ODR names and they are different, it is most > informative to output those. > This also covers types defined in different namespaces. */ > - if (TYPE_NAME (mt1) && TYPE_NAME (mt2) > - && TREE_CODE (TYPE_NAME (mt1)) == TYPE_DECL > - && TREE_CODE (TYPE_NAME (mt2)) == TYPE_DECL > - && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (mt1)) > - && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (mt2)) > - && DECL_ASSEMBLER_NAME (TYPE_NAME (mt1)) > - != DECL_ASSEMBLER_NAME (TYPE_NAME (mt2))) > - { > - char *name1 = xstrdup (cplus_demangle > - (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (mt1))), > - DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES)); > - char *name2 = cplus_demangle > - (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (mt2))), > - DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES); > + const char *odr1 = get_odr_name_for_type (mt1); > + const char *odr2 = get_odr_name_for_type (mt2); > + if (odr1 != NULL && odr2 != NULL && odr1 != odr2) > + { > + const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; > + char *name1 = xstrdup (cplus_demangle (odr1, opts)); > + char *name2 = xstrdup (cplus_demangle (odr2, opts));
This adds an xstrdup for name2. Is that intentional or just a pasto? The old code assumed that the demangler buffer wouldn't be reused by the diagnostics machinery, but maybe copying the buffer is more robust. In that case though, we need to free name2 in the same way that we already free name1. In the patch below I went for removing the xstrdup, but I can add the frees instead if that seems better. > diff --git a/gcc/tree.h b/gcc/tree.h > index 0f3cc5d7e5a..40a4fde6aec 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -6222,6 +6222,19 @@ fndecl_built_in_p (const_tree node, built_in_function > name) > && DECL_FUNCTION_CODE (node) == name); > } > > +/* If TYPE has mangled ODR name, return it. Otherwise return NULL. */ > + > +inline const char * > +get_odr_name_for_type (tree type) > +{ > + tree type_name = TYPE_NAME (type); > + if (type_name == NULL_TREE > + || !DECL_ASSEMBLER_NAME_SET_P (type_name)) > + return NULL; > + > + return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name)); > +} > + > /* A struct for encapsulating location information about an operator > and the operation built from it. > This drops the TYPE_DECL test from the original code above, which causes an ICE for C tags. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Thanks, Richard 2019-12-09 Richard Sandiford <richard.sandif...@arm.com> gcc/ * ipa-utils.h (get_odr_name_for_type): Check for a TYPE_DECL. * ipa-devirt.c (warn_types_mismatch): Don't call xstrdup for the second demangled name. gcc/testsuite/ * gcc.dg/lto/tag-1_0.c, gcc.dg/lto/tag-1_1.c: New test. Index: gcc/ipa-utils.h =================================================================== --- gcc/ipa-utils.h 2019-12-09 12:23:47.000000000 +0000 +++ gcc/ipa-utils.h 2019-12-09 12:23:48.326292463 +0000 @@ -256,6 +256,7 @@ get_odr_name_for_type (tree type) { tree type_name = TYPE_NAME (type); if (type_name == NULL_TREE + || TREE_CODE (type_name) != TYPE_DECL || !DECL_ASSEMBLER_NAME_SET_P (type_name)) return NULL; Index: gcc/ipa-devirt.c =================================================================== --- gcc/ipa-devirt.c 2019-12-09 12:23:47.000000000 +0000 +++ gcc/ipa-devirt.c 2019-12-09 12:23:48.326292463 +0000 @@ -1042,7 +1042,7 @@ warn_types_mismatch (tree t1, tree t2, l { const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; char *name1 = xstrdup (cplus_demangle (odr1, opts)); - char *name2 = xstrdup (cplus_demangle (odr2, opts)); + char *name2 = cplus_demangle (odr2, opts); if (name1 && name2 && strcmp (name1, name2)) { inform (loc_t1, Index: gcc/testsuite/gcc.dg/lto/tag-1_0.c =================================================================== --- /dev/null 2019-09-17 11:41:18.176664108 +0100 +++ gcc/testsuite/gcc.dg/lto/tag-1_0.c 2019-12-09 12:23:48.326292463 +0000 @@ -0,0 +1,5 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options { { -Wodr -flto } } } */ + +struct foo { int x; }; +struct foo a = {}; Index: gcc/testsuite/gcc.dg/lto/tag-1_1.c =================================================================== --- /dev/null 2019-09-17 11:41:18.176664108 +0100 +++ gcc/testsuite/gcc.dg/lto/tag-1_1.c 2019-12-09 12:23:48.326292463 +0000 @@ -0,0 +1,6 @@ +struct foo { short x; }; + +extern struct foo a; /* { dg-lto-warning {type of 'a' does not match original declaration} } */ +struct foo *ptr = &a; + +int main () { return 0; }