From 06e224f7e851bf8bf6bb5adfe52ae99de43197aa Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Tue, 26 Feb 2002 19:05:26 +0000 Subject: [PATCH] dwarf2out.c (gen_inlined_subroutine_die): If block is abstract, generate a die for the lexical block. * dwarf2out.c (gen_inlined_subroutine_die): If block is abstract, generate a die for the lexical block. From-SVN: r50056 --- gcc/ChangeLog | 5 +++ gcc/dwarf2out.c | 14 ++++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/debug/20020224-1.c | 60 +++++++++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/debug/20020224-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 670aafd4375..2918066933c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-02-26 Alexandre Oliva + + * dwarf2out.c (gen_inlined_subroutine_die): If block is abstract, + generate a die for the lexical block. + 2002-02-26 Kazu Hirata * config/h8300/h8300-protos.h: Add a prototype for diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 6313aeba2f4..f4c298a124a 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -10579,6 +10579,20 @@ gen_inlined_subroutine_die (stmt, context_die, depth) decls_for_scope (stmt, subr_die, depth); current_function_has_inlines = 1; } + else + /* We may get here if we're the outer block of function A that was + inlined into function B that was inlined into function C. When + generating debugging info for C, dwarf2out_abstract_function(B) + would mark all inlined blocks as abstract, including this one. + So, we wouldn't (and shouldn't) expect labels to be generated + for this one. Instead, just emit debugging info for + declarations within the block. This is particularly important + in the case of initializers of arguments passed from B to us: + if they're statement expressions containing declarations, we + wouldn't generate dies for their abstract variables, and then, + when generating dies for the real variables, we'd die (pun + intended :-) */ + gen_lexical_block_die (stmt, context_die, depth); } /* Generate a DIE for a field in a record, or structure. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0790f59710..8505241abef 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-02-26 Alexandre Oliva + + * gcc.dg/debug/20020224-1.c: New. + 2002-02-25 Kazu Hirata * gcc.c-torture/execute/960416-1.x: New. diff --git a/gcc/testsuite/gcc.dg/debug/20020224-1.c b/gcc/testsuite/gcc.dg/debug/20020224-1.c new file mode 100644 index 00000000000..c61a17aed10 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/20020224-1.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ + +/* Here's the deal: f3 is not inlined because it's too big, but f2 and + f1 are inlined into it. We used to fail to emit debugging info for + t1, because it was moved inside the (inlined) block of f1, marked + as abstract, then we'd crash. */ + +#define UNUSED __attribute__((unused)) +#define EXT __extension__ + +int undef(void); + +inline static void +f1 (int i UNUSED) +{ +} + +inline static void +f2 (void) +{ + f1 (EXT ({ int t1 UNUSED; undef (); })); +} + +inline static void +f3 (void) +{ + int v1 UNUSED; + int v2 UNUSED; + + EXT ({ int t2 UNUSED; if (0) undef (); 0; }) + && EXT ({ int t3 UNUSED; if (0) undef (); 0; }); + + if (1) + { + undef (); + if (1) + f2 (); + } + + { + undef (); + } +} + +inline static void +f4 (void) +{ + EXT ({ undef (); 1; }) && EXT ({ int t4 UNUSED = ({ 1; }); 1; }); + + { } + + EXT ({ int t5 UNUSED; if (0) undef (); 0; }); + + f4 (); + + undef (); + f3 (); + + return; +} -- 2.30.2