The testcase has failed since r9-5035, because obj_type_ref_class tries to look up an ODR type when no ODR type information is available. (The information was available earlier in the compilation, but was freed during pass_ipa_free_lang_data.) We then crash dereferencing the null get_odr_type result.
The test passes with -O2. However, it fails again if -fdump-tree-all is used, since obj_type_ref_class is called indirectly from the dump routines. Other code seems to create ODR type entries on the fly by passing "true" as the insert parameter. But since obj_type_ref_class is used by dump routines, I guess it should have no side-effects and should simply punt in this case. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK for master and branches? Richard 2020-05-14 Richard Sandiford <richard.sandif...@arm.com> gcc/ PR middle-end/95114 * ipa-devirt.c (obj_type_ref_class): Cope with a null return from get_odr_type. gcc/testsuite/ PR middle-end/95114 * g++.target/aarch64/pr95114.C: New test. --- gcc/ipa-devirt.c | 4 ++-- gcc/testsuite/g++.target/aarch64/pr95114.C | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.target/aarch64/pr95114.C diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index bd9f3441773..ac19eb75596 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1911,8 +1911,8 @@ obj_type_ref_class (const_tree ref) tree ret = TREE_TYPE (ref); if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (ret)) ret = TYPE_CANONICAL (ret); - else - ret = get_odr_type (ret)->type; + else if (odr_type ot = get_odr_type (ret)) + ret = ot->type; return ret; } diff --git a/gcc/testsuite/g++.target/aarch64/pr95114.C b/gcc/testsuite/g++.target/aarch64/pr95114.C new file mode 100644 index 00000000000..1689159e47c --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr95114.C @@ -0,0 +1,3 @@ +template<typename T> struct foo { virtual void f() = 0; }; +extern foo<__Int8x8_t> &x; +void f() { x.f(); }