From: Richard Henderson Date: Mon, 24 Dec 2001 08:45:59 +0000 (-0800) Subject: re PR debug/5163 (Internal compiler error in add_abstract_origin_attribute, at dwarf2... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b79d521356bff7a7db09804fb97c666013760665;p=gcc.git re PR debug/5163 (Internal compiler error in add_abstract_origin_attribute, at dwarf2out.c:9296) PR c/5163: * c-decl.c (duplicate_decls): As needed, set DECL_INLINE when we have a function body associated. Minor cleanups. (grokdeclarator): Do not set DECL_INLINE without a function body. * gcc.dg/20011223-1.c: New. * gcc.dg/inline-1.c: New. From-SVN: r48302 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7df5b189259..c526245a109 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2001-12-23 Richard Henderson + + PR c/5163: + * c-decl.c (duplicate_decls): As needed, set DECL_INLINE when + we have a function body associated. Minor cleanups. + (grokdeclarator): Do not set DECL_INLINE without a function body. + 2001-12-23 Richard Henderson * stmt.c (resolve_operand_names): Handle operand modifiers. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c7e1e0a872a..495425b2994 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1974,10 +1974,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level) /* If either decl says `inline', this fn is inline, unless its definition was passed already. */ if (DECL_DECLARED_INLINE_P (newdecl) - && DECL_DECLARED_INLINE_P (olddecl) == 0) - DECL_DECLARED_INLINE_P (olddecl) = 1; - - DECL_DECLARED_INLINE_P (newdecl) = DECL_DECLARED_INLINE_P (olddecl); + || DECL_DECLARED_INLINE_P (olddecl)) + DECL_DECLARED_INLINE_P (newdecl) = 1; DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); @@ -2003,9 +2001,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level) DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); } } + /* Also preserve various other info from the definition. */ - else if (! new_is_definition) - DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl); if (! new_is_definition) { DECL_RESULT (newdecl) = DECL_RESULT (olddecl); @@ -2016,12 +2013,27 @@ duplicate_decls (newdecl, olddecl, different_binding_level) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); + DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl); DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - if (DECL_INLINE (newdecl)) - DECL_ABSTRACT_ORIGIN (newdecl) - = (different_binding_level - ? DECL_ORIGIN (olddecl) - : DECL_ABSTRACT_ORIGIN (olddecl)); + + /* Set DECL_INLINE on the declaration if we've got a body + from which to instantiate. */ + if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl)) + { + DECL_INLINE (newdecl) = 1; + DECL_ABSTRACT_ORIGIN (newdecl) + = (different_binding_level + ? DECL_ORIGIN (olddecl) + : DECL_ABSTRACT_ORIGIN (olddecl)); + } + } + else + { + /* If a previous declaration said inline, mark the + definition as inlinable. */ + if (DECL_DECLARED_INLINE_P (newdecl) + && ! DECL_UNINLINABLE (newdecl)) + DECL_INLINE (newdecl) = 1; } } if (different_binding_level) @@ -5049,16 +5061,23 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) else if (inlinep) { /* Assume that otherwise the function can be inlined. */ - DECL_INLINE (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 1; - if (specbits & (1 << (int) RID_EXTERN)) - current_extern_inline = 1; + /* Do not mark bare declarations as DECL_INLINE. Doing so + in the presence of multiple declarations can result in + the abstract origin pointing between the declarations, + which will confuse dwarf2out. */ + if (initialized) + { + DECL_INLINE (decl) = 1; + if (specbits & (1 << (int) RID_EXTERN)) + current_extern_inline = 1; + } } /* If -finline-functions, assume it can be inlined. This does two things: let the function be deferred until it is actually needed, and let dwarf2 know that the function is inlinable. */ - else if (flag_inline_trees == 2) + else if (flag_inline_trees == 2 && initialized) { DECL_INLINE (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cddb9abb10c..c2bb361570d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2001-12-24 Richard Henderson + + * gcc.dg/20011223-1.c: New. + * gcc.dg/inline-1.c: New. + 2001-12-23 Richard Henderson * gcc.dg/asm-4.c: Test operand modifiers. diff --git a/gcc/testsuite/gcc.dg/20011223-1.c b/gcc/testsuite/gcc.dg/20011223-1.c new file mode 100644 index 00000000000..53f7f208f5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/20011223-1.c @@ -0,0 +1,12 @@ +/* Origin: PR c/5163 from aj@suse.de. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -g" } */ + +extern int bar (int); + +int +foo (void) +{ + extern int bar (int); + return bar (5); +} diff --git a/gcc/testsuite/gcc.dg/inline-1.c b/gcc/testsuite/gcc.dg/inline-1.c new file mode 100644 index 00000000000..17a9a2f7243 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline-1.c @@ -0,0 +1,28 @@ +/* Verify that DECL_INLINE gets copied between DECLs properly. */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +/* { dg-final { scan-assembler-not "xyzzy" } } */ + +/* Test that declaration followed by definition inlines. */ +static inline int xyzzy0 (int); +static int xyzzy0 (int x) { return x; } +int test0 (void) +{ + return xyzzy0 (5); +} + +/* Test that definition following declaration inlines. */ +static int xyzzy1 (int); +static inline int xyzzy1 (int x) { return x; } +int test1 (void) +{ + return xyzzy1 (5); +} + +/* Test that redeclaration inside a function body inlines. */ +extern inline int xyzzy2 (int x) { return x; } +int test2 (void) +{ + extern int xyzzy2 (int); + return xyzzy2 (5); +}