The following makes sure to generate early debug for globals that end up being pushed to the backend via the write_out_vars call in c_parse_final_cleanups. rest_of_decl_compilation is confused by seeing current_function_decl set and skips the debug-hook invocation because of that. So the easy fix is to flush out globals before starting the init function.
I verified we now properly generate early DIEs for e_missingvar and related structure types which otherwise with LTO are completely missing (and we ICE). Without LTO we may not be able to recover DIEs for those late once we start to run free-lang-data unconditionally. Bootstrap & regtest running on x86_64-unknown-linux-gnu. OK for trunk? Thanks, Richard. >From f73561b03a38a448115726a27749a06011507d65 Mon Sep 17 00:00:00 2001 From: Richard Guenther <rguent...@suse.de> Date: Tue, 17 Jul 2018 14:24:17 +0200 Subject: [PATCH] fix-pr86523-2 2018-07-17 Richard Biener <rguent...@suse.de> PR debug/86523 cp/ * decl2.c (c_parse_final_cleanups): Call write_out_vars before start_static_storage_duration_function sets current_function_decl. * g++.dg/lto/pr86523-3_0.C: New testcase. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index f8fc20e4093..d67ced097da 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4754,14 +4754,14 @@ c_parse_final_cleanups (void) inline, with resulting performance improvements. */ tree ssdf_body; + /* Make sure the back end knows about all the variables. */ + write_out_vars (vars); + /* Set the line and file, so that it is obviously not from the source file. */ input_location = locus_at_end_of_parsing; ssdf_body = start_static_storage_duration_function (ssdf_count); - /* Make sure the back end knows about all the variables. */ - write_out_vars (vars); - /* First generate code to do all the initializations. */ if (vars) do_static_initialization_or_destruction (vars, /*initp=*/true); diff --git a/gcc/testsuite/g++.dg/lto/pr86523-3_0.C b/gcc/testsuite/g++.dg/lto/pr86523-3_0.C new file mode 100644 index 00000000000..31063b8773a --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr86523-3_0.C @@ -0,0 +1,24 @@ +// { dg-lto-do link } +// { dg-require-effective-target fpic } +// { dg-require-effective-target shared } +// { dg-lto-options { { -fPIC -flto -g -shared } } } +class a { + int b; +}; +int const c = 0, d = 1, f = 2, g = 3; +struct B { + typedef a h; + h i; +}; +template <class> B j(); +template <class> struct k_context { static B const e_missingvar; }; +template <class l> B const k_context<l>::e_missingvar = j<l>(); +inline B m() { + switch (0) { + case c: + case d: + return k_context<int>::e_missingvar; + case f: + case g:; + } +}