------- Comment #4 from jakub at gcc dot gnu dot org 2009-03-05 15:02 ------- This is harder than I thought. My first attempt: --- integrate.c.xx2009-02-20 15:36:24.000000000 +0100 +++ integrate.c2009-03-05 15:46:23.000000000 +0100 @@ -173,7 +173,10 @@ set_block_abstract_flags (tree stmt, int for (local_decl = BLOCK_VARS (stmt); local_decl != NULL_TREE; local_decl = TREE_CHAIN (local_decl)) - set_decl_abstract_flags (local_decl, setting); + /* Don't mark local static variables, those are shared between all + inline/cloned copies. */ + if (TREE_CODE (local_decl) != VAR_DECL || !TREE_STATIC (local_decl)) + set_decl_abstract_flags (local_decl, setting);
for (subblock = BLOCK_SUBBLOCKS (stmt); subblock != NULL_TREE; works well for this testcase, the abstract DIE has DW_AT_location attribute for the local variable and DIEs for the ctor clones don't have any DIEs for this variable. But it creates worse output for C: extern void f (int *); static inline __attribute__((always_inline)) void foo (void) { static int staticvar1[4]; f (staticvar1); } void bar (void) { foo (); } void baz (void) { foo (); foo (); } Before the patch the abstract fn DIE contains a DIE for the static variable without DW_AT_location and the spots that inline this fn has DIE for the static variable with DW_AT_abstract_origin and DW_AT_location (the same in all cases). After the patch the abstract fn DIE's static variable DIE contains DW_AT_location, the spots that inline this have DIE for the static variable without DW_AT_abstract_origin and again with DW_AT_location. I'd say either the abstract origin DIE shouldn't contain DW_AT_location, but then all spots that use it should contain DW_AT_abstract_origin and DW_AT_location, or the abstract origin DIE should contain DW_AT_location and the clones shouldn't contain the DIE at all. So, I've tried a different patch: --- tree-cfg.c.jj2 2009-03-05 09:44:31.000000000 +0100 +++ tree-cfg.c 2009-03-05 14:57:46.000000000 +0100 @@ -1799,11 +1799,11 @@ remove_useless_stmts_bind (gimple_stmt_i tree var = NULL_TREE; /* Even if there are no gimple_bind_vars, there might be other decls in BLOCK_VARS rendering the GIMPLE_BIND not useless. */ - if (block) + if (block && !BLOCK_NUM_NONLOCALIZED_VARS (block)) for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) if (TREE_CODE (var) == IMPORTED_DECL) break; - if (var) + if (var || (block && BLOCK_NUM_NONLOCALIZED_VARS (block))) gsi_next (gsi); else { which prevents removing GIMPLE_BINDs that contain BLOCK_NONLOCALIZED_VARS in its gimple_bind_block (tree-ssa-live.c BLOCK removal does the same thing). Unfortunately this doesn't solve the original bug, because the abstract FUNCTION_DECL in the C++ ctor clone case is marked DECL_ABSTRACT already by the C++ FE, so when dwarf2out_abstract_function is called on it, was_abstract is true and so everything is set to DECL_ABSTRACT, but not reset afterwards. This means the VAR_DECL in clone's BLOCK_NONLOCALIZED_VARS has DECL_ABSTRACT set and thus won't have DW_AT_location emitted. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at gcc dot gnu dot | |org AssignedTo|jakub at gcc dot gnu dot org|unassigned at gcc dot gnu | |dot org Status|ASSIGNED |NEW http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39372