Commit 94dfccd1 by Jason Merrill Committed by Jason Merrill

decl.c (pushdecl): Matching decls for local externs are found in the current level.

        * decl.c (pushdecl): Matching decls for local externs are found in
        the current level.  Propagate linkage information from previous
        declarations.

From-SVN: r36011
parent bbfbf340
2000-08-27 Jason Merrill <jason@redhat.com>
* decl.c (pushdecl): Matching decls for local externs are found in
the current level. Propagate linkage information from previous
declarations.
2000-08-26 Gabriel Dos Reis <gdr@codesourcery.com>
* ir.texi (Expressions): Fix typo.
......
......@@ -3852,7 +3852,7 @@ pushdecl (x)
nesting. */
&& !(TREE_CODE (x) == FUNCTION_DECL && !DECL_INITIAL (x))
/* A local declaration for an `extern' variable is in the
scoped of the current namespace, not the current
scope of the current namespace, not the current
function. */
&& !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
&& !DECL_CONTEXT (x))
......@@ -3871,20 +3871,40 @@ pushdecl (x)
name = DECL_NAME (x);
if (name)
{
#if 0
/* Not needed...see below. */
char *file;
int line;
#endif
int different_binding_level = 0;
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
name = TREE_OPERAND (name, 0);
/* Namespace-scoped variables are not found in the current level. */
if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x))
/* In case this decl was explicitly namespace-qualified, look it
up in its namespace context. */
if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x)
&& namespace_bindings_p ())
t = namespace_binding (name, DECL_CONTEXT (x));
else
t = lookup_name_current_level (name);
/* [basic.link] If there is a visible declaration of an entity
with linkage having the same name and type, ignoring entities
declared outside the innermost enclosing namespace scope, the
block scope declaration declares that same entity and
receives the linkage of the previous declaration. */
if (! t && current_function_decl && x != current_function_decl
&& (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
&& DECL_EXTERNAL (x))
{
/* Look in block scope. */
t = IDENTIFIER_VALUE (name);
/* Or in the innermost namespace. */
if (! t)
t = namespace_binding (name, DECL_CONTEXT (x));
/* Does it have linkage? */
if (t && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
t = NULL_TREE;
if (t)
different_binding_level = 1;
}
/* If we are declaring a function, and the result of name-lookup
was an OVERLOAD, look for an overloaded instance that is
actually the same as the function we are declaring. (If
......@@ -3919,7 +3939,16 @@ pushdecl (x)
}
else if (t != NULL_TREE)
{
if (TREE_CODE (t) == PARM_DECL)
if (different_binding_level)
{
if (decls_match (x, t))
/* The standard only says that the local extern
inherits linkage from the previous decl; in
particular, default args are not shared. It would
be nice to propagate inlining info, though. FIXME. */
TREE_PUBLIC (x) = TREE_PUBLIC (t);
}
else if (TREE_CODE (t) == PARM_DECL)
{
if (DECL_CONTEXT (t) == NULL_TREE)
fatal ("parse errors have confused me too much");
......
// Testcase for proper scoping of local externs.
int x = 1;
int main()
{
int x = 2;
{
extern int x;
return (x != 1);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment