summaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index b6ffd614fd1..ca33a4c99f3 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1900,6 +1900,7 @@ pushdecl (x)
{
char *file;
int line;
+ int declared_global;
/* Don't type check externs here when -traditional. This is so that
code with conflicting declarations inside blocks will get warnings
@@ -1921,6 +1922,9 @@ pushdecl (x)
line = DECL_SOURCE_LINE (t);
}
+ /* duplicate_decls might write to TREE_PUBLIC (x) and DECL_EXTERNAL (x)
+ to make it identical to the initial declaration. */
+ declared_global = TREE_PUBLIC (x) || DECL_EXTERNAL (x);
if (t != 0 && duplicate_decls (x, t))
{
if (TREE_CODE (t) == PARM_DECL)
@@ -1934,7 +1938,10 @@ pushdecl (x)
warn. But don't complain if -traditional,
since traditional compilers don't complain. */
if (!flag_traditional && TREE_PUBLIC (name)
+
+ /* should this be '&& ! declared_global' ? */
&& ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x)
+
/* We used to warn also for explicit extern followed by static,
but sometimes you need to do it that way. */
&& IDENTIFIER_IMPLICIT_DECL (name) != 0)
@@ -1949,7 +1956,9 @@ pushdecl (x)
/* If this is a global decl, and there exists a conflicting local
decl in a parent block, then we can't return as yet, because we
need to register this decl in the current binding block. */
- if (! TREE_PUBLIC (x) || lookup_name (name) == t)
+ /* A test for TREE_PUBLIC (x) will fail for variables that have
+ been declared static first, and extern now. */
+ if (! declared_global || lookup_name (name) == t)
return t;
}