This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR debug/14114


Hi,

The compiler ICEs in dwarf2out.c at -O2 -g on the following testcase:

void a()
{
  void c();
  c();
}

void b()
{
  void c();
}

void c() {}

a regression present on mainline and 3.4 branch.


The problem is that the definition tree for 'c' is sent twice to the DWARF-2 
back-end (the first time for 'void c() {}', the second time for 'void c();' 
from 'a') and the back-end is wired to abort in this case, unless an error 
has previously been encountered.

The sequence of events is described below, and compiling with -Wshadow sheds 
some light on the problem:
pr14114.c: In function `b':
pr14114.c:9: warning: declaration of 'c' shadows a global declaration
pr14114.c:9: warning: shadowed declaration is here

The compiler thinks that the declaration 'void c();' from 'b' shadows the 
declaration 'void c();' from 'a'.  So, when leaving the scope of 'b', it 
restores the declaration of 'c' from 'a' in the global scope, thus 
effectively promoting it.  Then, when the definition of 'c' is seen, it is 
merged with the declaration of 'c' from 'a' and this declaration becomes the 
definition of 'c', which is then sent twice to the DWARF-2 back-end.


The proposed fix is to teach pushdecl not to schedule the restoration of the 
declaration from 'a' when it is parsing 'b'.  Bootstrapped/regtested on 
i586-redhat-linux (3.4 branch).  OK for mainline and 3.4 branch?


2004-03-03  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR debug/14114
	* c-decl (pushdecl): Do not record a previous, not-in-scope,
	external decl for restoration.


2004-03-03  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* gcc.dg/decl-4.c: New test.


-- 
Eric Botcazou
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.470.4.5
diff -u -p -r1.470.4.5 c-decl.c
--- c-decl.c	8 Feb 2004 01:52:42 -0000	1.470.4.5
+++ c-decl.c	2 Mar 2004 17:54:30 -0000
@@ -1671,7 +1671,7 @@ pushdecl (tree x)
 
   if (name)
     {
-      tree old;
+      tree old, ext;
 
       if (warn_nested_externs
 	  && scope != global_scope
@@ -1706,7 +1706,7 @@ pushdecl (tree x)
 	     decl for this identifier.  (C99 6.2.7p2: All declarations
 	     that refer to the same object or function shall have
 	     compatible type; otherwise, the behavior is undefined.)  */
- 	  tree ext = any_external_decl (name);
+ 	  ext = any_external_decl (name);
 	  if (ext)
 	    {
 	      if (duplicate_decls (x, ext))
@@ -1715,6 +1715,8 @@ pushdecl (tree x)
 	  else
 	    record_external_decl (x);
 	}
+      else
+	ext = 0;
 
       if (TREE_CODE (x) == TYPE_DECL)
 	clone_underlying_type (x);
@@ -1722,11 +1724,13 @@ pushdecl (tree x)
       /* If storing a local value, there may already be one
 	 (inherited).  If so, record it for restoration when this
 	 scope ends.  Take care not to do this if we are replacing an
-	 older decl in the same scope (i.e.  duplicate_decls returned
-	 false, above).  */
+	 older decl in the same scope (i.e. the first duplicate_decls
+	 returned false, above) or have found a previous, not-in-scope,
+	 external decl.  */
       if (scope != global_scope
 	  && IDENTIFIER_SYMBOL_VALUE (name)
-	  && IDENTIFIER_SYMBOL_VALUE (name) != old)
+	  && IDENTIFIER_SYMBOL_VALUE (name) != old
+	  && IDENTIFIER_SYMBOL_VALUE (name) != ext)
 	{
 	  warn_if_shadowing (x, IDENTIFIER_SYMBOL_VALUE (name));
 	  scope->shadowed = tree_cons (name, IDENTIFIER_SYMBOL_VALUE (name),
/* PR debug/14114 */
/* Origin: <snyder@fnal.gov> */
/* { dg-do compile } */
/* { dg-options "-O2 -g" } */

/* This used to fail because the compiler thought that the
   declaration of 'c' from 'b' was shadowing that from 'a'.  */

void a()
{
  void c();
  c();
}

void b()
{
  void c();
}

void c() {}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]