mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-21 03:39:29 +08:00
c-decl.c (struct binding_level): Add shadowed_tags and function_body...
2003-04-10 Zack Weinberg <zack@codesourcery.com> * c-decl.c (struct binding_level): Add shadowed_tags and function_body; remove this_block, tag_transparent, and subblocks_tag_transparent; update comments. (clear_binding_level, lookup_tag_reverse): Kill. (make_binding_level): Use ggc_alloc_cleared or memset. (lookup_tag): Remove struct binding_level* parameter. All callers changed. Just look at IDENTIFIER_TAG_VALUE, and current_binding_level->tags if asked for thislevel_only or if we might have to diagnose "struct foo; union foo;" (pushlevel): Ignore argument. Do not push another binding level on the transition from the parameters to the top level of the function body; just tweak the flags and proceed. (poplevel): Overhaul. Clear IDENTIFIER_TAG_VALUEs; on exiting a function body, separate the parameter list from the top-level local variables. (set_block): Do nothing. (pushtag): Set IDENTIFIER_TAG_VALUE and add an entry to shadowed_tags if necessary. (warn_if_shadowing): Nuke the special case for local shadowing parameter. (pushdecl): Do not create a shadow entry if we are replacing an older decl in the same binding level. (pushdecl_function_level): Tweak for new way of indicating function scope. (shadow_tag_warned): Use TYPE_NAME, not lookup_tag_reverse. (start_function): Don't set subblocks_tag_transparent. (finish_function): Fix up the binding_level stack for totally empty functions. Otherwise, don't call poplevel. * c-common.c (shadow_warning): MANDATORY argument is no longer necessary. Always use plain warning. * c-common.h: Update to match. * cfglayout.c (scope_to_insns_initialize): Clear block when we hit the FUNCTION_DECL. * function.c: Do not create cyclic tree structure. 2003-04-10 Zack Weinberg <zack@codesourcery.com> * c-tree.h (struct lang_identifier): Replace global_value, local_value members with symbol_value, tag_value. Kill implicit_decl and limbo_value. (IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_LOCAL_VALUE, IDENTIFIER_LIMBO_VALUE, IDENTIFIER_IMPLICIT_DECL, C_MISSING_PROTOTYPE_WARNED): Kill. (IDENTIFIER_SYMBOL_VALUE, IDENTIFIER_TAG_VALUE, C_DECL_IMPLICIT, C_DECL_ISNT_PROTOTYPE): New. (C_DECL_ANTICIPATED): Rename to C_DECL_INVISIBLE. (implicit_decl_warning, lookup_name_current_level, record_function_scope_shadow): Don't prototype. (pushdecl_function_level): Prototype. * c-decl.c (truly_local_externals): New variable. (struct binding_level): Adjust commentary. (get_function_binding_level, clear_limbo_values, record_function_scope_shadow): Kill. (lookup_name_current_level, implicit_decl_warning): Are now static. (any_external_decl, record_external_decl): New static functions. (clone_underlying type): Split out of pushdecl. (c_print_identifier): Update to match changes to struct lang_identifier. (poplevel): Delete #if 0 block. Make externals invisible instead of clearing their IDENTIFIER_SYMBOL_VALUEs. Don't call clear_limbo_values. Refer to IDENTIFIER_SYMBOL_VALUE not IDENTIFIER_GLOBAL_VALUE or IDENTIFIER_LOCAL_VALUE. (duplicate-decls): For real parm decl after a forward decl, set TREE_ASM_WRITTEN here. Allow void foo(...) followed by foo(...) { } with only a warning. Say whether a previous declaration was implicit. (warn_if_shadowing): Now handles all shadowing, not just local-over-local. Clarify comments. (pushdecl): Rewritten. There is no longer a distinction between global and local symbol values; they're all IDENTIFIER_SYMBOL_VALUE. Call record_external_decl on all DECL_EXTERNAL decls, and use any_external_decl to check against previous externals. Kill #if 0 blocks. Don't tolerate error_mark_node being NULL. (pushdecl_top_level): Handle only those cases which Objective C (the only user) needs. (pushdecl_function_level): New function. (implicitly_declare): Create ordinary decls with C_DECL_IMPLICIT set. Recycle old decls, however they got created. (lookup_name): It's always IDENTIFIER_SYMBOL_VALUE. Return 0 for C_DECL_INVISIBLE symbols. (lookup_name_current_level): Likewise. Use chain_member. (c_make_fname_decl): Don't muck with DECL_CONTEXT. Use pushdecl_function_level. (builtin_function): Use C_DECL_INVISIBLE. (start_function): Don't muck with IDENTIFIER_IMPLICIT_DECL. Use C_DECL_ISNT_PROTOTYPE and C_DECL_IMPLICIT. (store_parm_decls): It's IDENTIFIER_SYMBOL_VALUE now. (identifier_global_value): Same. Must scan global_binding_level in extremis. * c-typeck.c (undeclared_variable): New static function, split from build_external_ref. (build_external_ref): Use DECL_CONTEXT, not IDENTIFIER_LOCAL_VALUE, to decide whether a local hides an instance variable. Restructure for clarity. * objc/objc-act.c: Use identifier_global_value, not IDENTIFIER_GLOBAL_VALUE. cp: * decl.c: Update all calls to shadow_warning. testsuite: * gcc.c-torture/execute/builtin-noret-2.c: New. * gcc.c-torture/execute/builtin-noret-2.x: New. XFAIL builtin-noret-2.c at -O1 and above. * gcc.dg/redecl.c: New. * gcc.dg/Wshadow-1.c: Update error regexps. From-SVN: r65460
This commit is contained in:
parent
b1e0a93ee5
commit
339a28b96a
105
gcc/ChangeLog
105
gcc/ChangeLog
@ -1,3 +1,108 @@
|
||||
2003-04-10 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* c-decl.c (struct binding_level): Add shadowed_tags and
|
||||
function_body; remove this_block, tag_transparent, and
|
||||
subblocks_tag_transparent; update comments.
|
||||
(clear_binding_level, lookup_tag_reverse): Kill.
|
||||
(make_binding_level): Use ggc_alloc_cleared or memset.
|
||||
(lookup_tag): Remove struct binding_level* parameter. All
|
||||
callers changed. Just look at IDENTIFIER_TAG_VALUE, and
|
||||
current_binding_level->tags if asked for thislevel_only or if
|
||||
we might have to diagnose "struct foo; union foo;"
|
||||
(pushlevel): Ignore argument. Do not push another binding
|
||||
level on the transition from the parameters to the top level
|
||||
of the function body; just tweak the flags and proceed.
|
||||
(poplevel): Overhaul. Clear IDENTIFIER_TAG_VALUEs; on exiting
|
||||
a function body, separate the parameter list from the
|
||||
top-level local variables.
|
||||
(set_block): Do nothing.
|
||||
(pushtag): Set IDENTIFIER_TAG_VALUE and add an entry to
|
||||
shadowed_tags if necessary.
|
||||
(warn_if_shadowing): Nuke the special case for local shadowing
|
||||
parameter.
|
||||
(pushdecl): Do not create a shadow entry if we are replacing
|
||||
an older decl in the same binding level.
|
||||
(pushdecl_function_level): Tweak for new way of indicating
|
||||
function scope.
|
||||
(shadow_tag_warned): Use TYPE_NAME, not lookup_tag_reverse.
|
||||
(start_function): Don't set subblocks_tag_transparent.
|
||||
(finish_function): Fix up the binding_level stack for totally
|
||||
empty functions. Otherwise, don't call poplevel.
|
||||
|
||||
* c-common.c (shadow_warning): MANDATORY argument is no longer
|
||||
necessary. Always use plain warning.
|
||||
* c-common.h: Update to match.
|
||||
|
||||
* cfglayout.c (scope_to_insns_initialize): Clear block when we
|
||||
hit the FUNCTION_DECL.
|
||||
* function.c: Do not create cyclic tree structure.
|
||||
|
||||
2003-04-10 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* c-tree.h (struct lang_identifier): Replace global_value,
|
||||
local_value members with symbol_value, tag_value. Kill
|
||||
implicit_decl and limbo_value.
|
||||
(IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_LOCAL_VALUE,
|
||||
IDENTIFIER_LIMBO_VALUE, IDENTIFIER_IMPLICIT_DECL,
|
||||
C_MISSING_PROTOTYPE_WARNED): Kill.
|
||||
(IDENTIFIER_SYMBOL_VALUE, IDENTIFIER_TAG_VALUE,
|
||||
C_DECL_IMPLICIT, C_DECL_ISNT_PROTOTYPE): New.
|
||||
(C_DECL_ANTICIPATED): Rename to C_DECL_INVISIBLE.
|
||||
(implicit_decl_warning, lookup_name_current_level,
|
||||
record_function_scope_shadow): Don't prototype.
|
||||
(pushdecl_function_level): Prototype.
|
||||
|
||||
* c-decl.c (truly_local_externals): New variable.
|
||||
(struct binding_level): Adjust commentary.
|
||||
(get_function_binding_level, clear_limbo_values,
|
||||
record_function_scope_shadow): Kill.
|
||||
(lookup_name_current_level, implicit_decl_warning): Are now static.
|
||||
(any_external_decl, record_external_decl): New static functions.
|
||||
(clone_underlying type): Split out of pushdecl.
|
||||
(c_print_identifier): Update to match changes to struct
|
||||
lang_identifier.
|
||||
(poplevel): Delete #if 0 block. Make externals invisible
|
||||
instead of clearing their IDENTIFIER_SYMBOL_VALUEs. Don't
|
||||
call clear_limbo_values. Refer to IDENTIFIER_SYMBOL_VALUE not
|
||||
IDENTIFIER_GLOBAL_VALUE or IDENTIFIER_LOCAL_VALUE.
|
||||
(duplicate-decls): For real parm decl after a forward decl,
|
||||
set TREE_ASM_WRITTEN here. Allow void foo(...) followed by
|
||||
foo(...) { } with only a warning. Say whether a previous
|
||||
declaration was implicit.
|
||||
(warn_if_shadowing): Now handles all shadowing, not just
|
||||
local-over-local. Clarify comments.
|
||||
(pushdecl): Rewritten. There is no longer a distinction
|
||||
between global and local symbol values; they're all
|
||||
IDENTIFIER_SYMBOL_VALUE. Call record_external_decl on all
|
||||
DECL_EXTERNAL decls, and use any_external_decl to check
|
||||
against previous externals. Kill #if 0 blocks. Don't
|
||||
tolerate error_mark_node being NULL.
|
||||
(pushdecl_top_level): Handle only those cases which
|
||||
Objective C (the only user) needs.
|
||||
(pushdecl_function_level): New function.
|
||||
(implicitly_declare): Create ordinary decls with
|
||||
C_DECL_IMPLICIT set. Recycle old decls, however they got
|
||||
created.
|
||||
(lookup_name): It's always IDENTIFIER_SYMBOL_VALUE. Return 0
|
||||
for C_DECL_INVISIBLE symbols.
|
||||
(lookup_name_current_level): Likewise. Use chain_member.
|
||||
(c_make_fname_decl): Don't muck with DECL_CONTEXT.
|
||||
Use pushdecl_function_level.
|
||||
(builtin_function): Use C_DECL_INVISIBLE.
|
||||
(start_function): Don't muck with IDENTIFIER_IMPLICIT_DECL.
|
||||
Use C_DECL_ISNT_PROTOTYPE and C_DECL_IMPLICIT.
|
||||
(store_parm_decls): It's IDENTIFIER_SYMBOL_VALUE now.
|
||||
(identifier_global_value): Same. Must scan
|
||||
global_binding_level in extremis.
|
||||
|
||||
* c-typeck.c (undeclared_variable): New static function, split
|
||||
from build_external_ref.
|
||||
(build_external_ref): Use DECL_CONTEXT, not
|
||||
IDENTIFIER_LOCAL_VALUE, to decide whether a local hides
|
||||
an instance variable. Restructure for clarity.
|
||||
* objc/objc-act.c: Use identifier_global_value, not
|
||||
IDENTIFIER_GLOBAL_VALUE.
|
||||
|
||||
2003-04-08 Jonathan Wakely <redi@gcc.gnu.org>
|
||||
|
||||
* doc/extend.texi (Template Instantiation): Refer to ISO standard,
|
||||
|
@ -4778,12 +4778,10 @@ c_common_insert_default_attributes (decl)
|
||||
}
|
||||
|
||||
/* Output a -Wshadow warning MSGCODE about NAME, and give the location
|
||||
of the previous declaration DECL. MANDATORY says whether this is a
|
||||
mandatory warning (i.e. use pedwarn). */
|
||||
of the previous declaration DECL. */
|
||||
void
|
||||
shadow_warning (msgcode, mandatory, name, decl)
|
||||
shadow_warning (msgcode, name, decl)
|
||||
enum sw_kind msgcode;
|
||||
int mandatory; /* really bool */
|
||||
const char *name;
|
||||
tree decl;
|
||||
{
|
||||
@ -4793,7 +4791,7 @@ shadow_warning (msgcode, mandatory, name, decl)
|
||||
/* SW_GLOBAL */ N_("declaration of \"%s\" shadows a global declaration")
|
||||
};
|
||||
|
||||
(mandatory ? pedwarn : warning) (msgs[msgcode], name);
|
||||
warning (msgs[msgcode], name);
|
||||
warning_with_file_and_line (DECL_SOURCE_FILE (decl),
|
||||
DECL_SOURCE_LINE (decl),
|
||||
"shadowed declaration is here");
|
||||
|
@ -335,7 +335,7 @@ extern tree c_begin_while_stmt PARAMS ((void));
|
||||
extern void c_finish_while_stmt_cond PARAMS ((tree, tree));
|
||||
|
||||
enum sw_kind { SW_PARAM = 0, SW_LOCAL, SW_GLOBAL };
|
||||
extern void shadow_warning PARAMS ((enum sw_kind, int,
|
||||
extern void shadow_warning PARAMS ((enum sw_kind,
|
||||
const char *, tree));
|
||||
|
||||
/* Extra information associated with a DECL. Other C dialects extend
|
||||
|
1317
gcc/c-decl.c
1317
gcc/c-decl.c
File diff suppressed because it is too large
Load Diff
66
gcc/c-tree.h
66
gcc/c-tree.h
@ -1,6 +1,6 @@
|
||||
/* Definitions for C parsing and type checking.
|
||||
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -37,11 +37,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
struct lang_identifier GTY(())
|
||||
{
|
||||
struct c_common_identifier common_id;
|
||||
tree global_value;
|
||||
tree local_value;
|
||||
tree symbol_value;
|
||||
tree tag_value;
|
||||
tree label_value;
|
||||
tree implicit_decl;
|
||||
tree limbo_value;
|
||||
};
|
||||
|
||||
/* The resulting tree type. */
|
||||
@ -70,26 +68,17 @@ struct lang_decl GTY(())
|
||||
/* Macros for access to language-specific slots in an identifier. */
|
||||
/* Each of these slots contains a DECL node or null. */
|
||||
|
||||
/* This represents the value which the identifier has in the
|
||||
file-scope namespace. */
|
||||
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->global_value)
|
||||
/* This represents the value which the identifier has in the current
|
||||
scope. */
|
||||
#define IDENTIFIER_LOCAL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->local_value)
|
||||
/* This represents the value which the identifier has as a label in
|
||||
the current label scope. */
|
||||
/* The value of the identifier in the namespace of "ordinary identifiers"
|
||||
(data objects, enum constants, functions, typedefs). */
|
||||
#define IDENTIFIER_SYMBOL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->symbol_value)
|
||||
/* The value of the identifier in the namespace of struct, union,
|
||||
and enum tags. */
|
||||
#define IDENTIFIER_TAG_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->tag_value)
|
||||
/* The value of the identifier in the namespace of labels. */
|
||||
#define IDENTIFIER_LABEL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->label_value)
|
||||
/* This records the extern decl of this identifier, if it has had one
|
||||
at any point in this compilation. */
|
||||
#define IDENTIFIER_LIMBO_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->limbo_value)
|
||||
/* This records the implicit function decl of this identifier, if it
|
||||
has had one at any point in this compilation. */
|
||||
#define IDENTIFIER_IMPLICIT_DECL(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->implicit_decl)
|
||||
|
||||
/* In identifiers, C uses the following fields in a special way:
|
||||
TREE_PUBLIC to record that there was a previous local extern decl.
|
||||
@ -129,13 +118,6 @@ struct lang_type GTY(())
|
||||
#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
|
||||
#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
|
||||
|
||||
#if 0 /* Not used. */
|
||||
/* Record whether a decl for a function or function pointer has
|
||||
already been mentioned (in a warning) because it was called
|
||||
but didn't have a prototype. */
|
||||
#define C_MISSING_PROTOTYPE_WARNED(DECL) DECL_LANG_FLAG_2 (DECL)
|
||||
#endif
|
||||
|
||||
/* Store a value in that field. */
|
||||
#define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \
|
||||
(TREE_COMPLEXITY (EXP) = (int) (CODE))
|
||||
@ -147,10 +129,22 @@ struct lang_type GTY(())
|
||||
return type. */
|
||||
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||
|
||||
/* Nonzero for a declaration of a built in function if there has been no
|
||||
occasion that would declare the function in ordinary C.
|
||||
Using the function draws a pedantic warning in this case. */
|
||||
#define C_DECL_ANTICIPATED(EXP) DECL_LANG_FLAG_3 (EXP)
|
||||
/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */
|
||||
#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
|
||||
|
||||
/* Nonzero for a declaration of an external object which is not
|
||||
currently in scope. This is either a built-in declaration of
|
||||
a library function, before a real declaration has been seen,
|
||||
or a declaration that appeared in an inner scope that has ended. */
|
||||
#define C_DECL_INVISIBLE(EXP) DECL_LANG_FLAG_3 (EXP)
|
||||
|
||||
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
|
||||
N.B. Could be simplified if all built-in decls had complete prototypes
|
||||
(but this is presently difficult because some of them need FILE*). */
|
||||
#define C_DECL_ISNT_PROTOTYPE(EXP) \
|
||||
(EXP == 0 \
|
||||
|| (TYPE_ARG_TYPES (TREE_TYPE (EXP)) == 0 \
|
||||
&& !DECL_BUILT_IN (EXP)))
|
||||
|
||||
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
|
||||
TYPE_ARG_TYPES for functions with prototypes, but created for functions
|
||||
@ -207,11 +201,9 @@ extern tree grokfield PARAMS ((const char *, int, tree
|
||||
extern tree groktypename PARAMS ((tree));
|
||||
extern tree groktypename_in_parm_context PARAMS ((tree));
|
||||
extern tree implicitly_declare PARAMS ((tree));
|
||||
extern void implicit_decl_warning PARAMS ((tree));
|
||||
extern int in_parm_level_p PARAMS ((void));
|
||||
extern void keep_next_level PARAMS ((void));
|
||||
extern tree lookup_name PARAMS ((tree));
|
||||
extern tree lookup_name_current_level PARAMS ((tree));
|
||||
extern void parmlist_tags_warning PARAMS ((void));
|
||||
extern void pending_xref_error PARAMS ((void));
|
||||
extern void c_push_function_context PARAMS ((struct function *));
|
||||
@ -220,8 +212,8 @@ extern void pop_label_level PARAMS ((void));
|
||||
extern void push_label_level PARAMS ((void));
|
||||
extern void push_parm_decl PARAMS ((tree));
|
||||
extern tree pushdecl_top_level PARAMS ((tree));
|
||||
extern tree pushdecl_function_level PARAMS ((tree, tree));
|
||||
extern void pushtag PARAMS ((tree, tree));
|
||||
extern void record_function_scope_shadow PARAMS ((tree));
|
||||
extern tree set_array_declarator_type PARAMS ((tree, tree, int));
|
||||
extern tree shadow_label PARAMS ((tree));
|
||||
extern void shadow_tag PARAMS ((tree));
|
||||
|
114
gcc/c-typeck.c
114
gcc/c-typeck.c
@ -1,6 +1,6 @@
|
||||
/* Build expressions with type checking for C compiler.
|
||||
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -59,6 +59,7 @@ static int type_lists_compatible_p PARAMS ((tree, tree));
|
||||
static tree decl_constant_value_for_broken_optimization PARAMS ((tree));
|
||||
static tree default_function_array_conversion PARAMS ((tree));
|
||||
static tree lookup_field PARAMS ((tree, tree));
|
||||
static void undeclared_variable PARAMS ((tree));
|
||||
static tree convert_arguments PARAMS ((tree, tree, tree, tree));
|
||||
static tree pointer_diff PARAMS ((tree, tree));
|
||||
static tree unary_complex_lvalue PARAMS ((enum tree_code, tree, int));
|
||||
@ -1375,6 +1376,38 @@ build_array_ref (array, index)
|
||||
}
|
||||
}
|
||||
|
||||
/* Issue an error message for a reference to an undeclared variable ID,
|
||||
including a reference to a builtin outside of function-call context.
|
||||
Arrange to suppress further errors for the same identifier. */
|
||||
static void
|
||||
undeclared_variable (id)
|
||||
tree id;
|
||||
{
|
||||
if (current_function_decl == 0)
|
||||
{
|
||||
error ("`%s' undeclared here (not in a function)",
|
||||
IDENTIFIER_POINTER (id));
|
||||
IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("`%s' undeclared (first use in this function)",
|
||||
IDENTIFIER_POINTER (id));
|
||||
|
||||
if (! undeclared_variable_notice)
|
||||
{
|
||||
error ("(Each undeclared identifier is reported only once");
|
||||
error ("for each function it appears in.)");
|
||||
undeclared_variable_notice = 1;
|
||||
}
|
||||
|
||||
/* Set IDENTIFIER_SYMBOL_VALUE (id) to error_mark_node
|
||||
at function scope. This suppresses further warnings
|
||||
about this undeclared identifier in this function. */
|
||||
pushdecl_function_level (error_mark_node, id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Build an external reference to identifier ID. FUN indicates
|
||||
whether this will be used for a function call. */
|
||||
tree
|
||||
@ -1386,70 +1419,12 @@ build_external_ref (id, fun)
|
||||
tree decl = lookup_name (id);
|
||||
tree objc_ivar = lookup_objc_ivar (id);
|
||||
|
||||
if (decl && TREE_DEPRECATED (decl))
|
||||
warn_deprecated_use (decl);
|
||||
|
||||
if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl))
|
||||
{
|
||||
if (objc_ivar)
|
||||
ref = objc_ivar;
|
||||
else if (fun)
|
||||
{
|
||||
if (!decl || decl == error_mark_node)
|
||||
/* Ordinary implicit function declaration. */
|
||||
ref = implicitly_declare (id);
|
||||
else
|
||||
{
|
||||
/* Implicit declaration of built-in function. Don't
|
||||
change the built-in declaration, but don't let this
|
||||
go by silently, either. */
|
||||
implicit_decl_warning (id);
|
||||
|
||||
/* only issue this warning once */
|
||||
C_DECL_ANTICIPATED (decl) = 0;
|
||||
ref = decl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Don't complain about something that's already been
|
||||
complained about. */
|
||||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Reference to undeclared variable, including reference to
|
||||
builtin outside of function-call context. */
|
||||
if (current_function_decl == 0)
|
||||
error ("`%s' undeclared here (not in a function)",
|
||||
IDENTIFIER_POINTER (id));
|
||||
else
|
||||
{
|
||||
error ("`%s' undeclared (first use in this function)",
|
||||
IDENTIFIER_POINTER (id));
|
||||
|
||||
if (! undeclared_variable_notice)
|
||||
{
|
||||
error ("(Each undeclared identifier is reported only once");
|
||||
error ("for each function it appears in.)");
|
||||
undeclared_variable_notice = 1;
|
||||
}
|
||||
|
||||
/* Set IDENTIFIER_LOCAL_VALUE (id) to error_mark_node and
|
||||
add a function-scope shadow entry which will undo that.
|
||||
This suppresses further warnings about this undeclared
|
||||
identifier in this function. */
|
||||
record_function_scope_shadow (id);
|
||||
IDENTIFIER_LOCAL_VALUE (id) = error_mark_node;
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (decl && decl != error_mark_node)
|
||||
{
|
||||
/* Properly declared variable or function reference. */
|
||||
if (!objc_ivar)
|
||||
ref = decl;
|
||||
else if (decl != objc_ivar && IDENTIFIER_LOCAL_VALUE (id))
|
||||
else if (decl != objc_ivar && DECL_CONTEXT (decl) != 0)
|
||||
{
|
||||
warning ("local declaration of `%s' hides instance variable",
|
||||
IDENTIFIER_POINTER (id));
|
||||
@ -1458,10 +1433,27 @@ build_external_ref (id, fun)
|
||||
else
|
||||
ref = objc_ivar;
|
||||
}
|
||||
else if (objc_ivar)
|
||||
ref = objc_ivar;
|
||||
else if (fun)
|
||||
/* Implicit function declaration. */
|
||||
ref = implicitly_declare (id);
|
||||
else if (decl == error_mark_node)
|
||||
/* Don't complain about something that's already been
|
||||
complained about. */
|
||||
return error_mark_node;
|
||||
else
|
||||
{
|
||||
undeclared_variable (id);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (TREE_TYPE (ref) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_DEPRECATED (ref))
|
||||
warn_deprecated_use (ref);
|
||||
|
||||
if (!skip_evaluation)
|
||||
assemble_external (ref);
|
||||
TREE_USED (ref) = 1;
|
||||
|
@ -239,6 +239,8 @@ scope_to_insns_initialize ()
|
||||
break;
|
||||
case NOTE_INSN_BLOCK_END:
|
||||
block = BLOCK_SUPERCONTEXT (block);
|
||||
if (block && TREE_CODE (block) == FUNCTION_DECL)
|
||||
block = 0;
|
||||
delete_insn (insn);
|
||||
break;
|
||||
default:
|
||||
|
@ -1,3 +1,7 @@
|
||||
2003-04-10 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* decl.c: Update all calls to shadow_warning.
|
||||
|
||||
2003-04-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* class.c (layout_class_type): Correct handling for overlong
|
||||
|
@ -4001,7 +4001,7 @@ pushdecl (tree x)
|
||||
}
|
||||
|
||||
if (warn_shadow && !err)
|
||||
shadow_warning (SW_PARAM, false,
|
||||
shadow_warning (SW_PARAM,
|
||||
IDENTIFIER_POINTER (name), oldlocal);
|
||||
}
|
||||
|
||||
@ -4019,12 +4019,12 @@ pushdecl (tree x)
|
||||
IDENTIFIER_POINTER (name));
|
||||
else if (oldlocal != NULL_TREE
|
||||
&& TREE_CODE (oldlocal) == VAR_DECL)
|
||||
shadow_warning (SW_LOCAL, false,
|
||||
shadow_warning (SW_LOCAL,
|
||||
IDENTIFIER_POINTER (name), oldlocal);
|
||||
else if (oldglobal != NULL_TREE
|
||||
&& TREE_CODE (oldglobal) == VAR_DECL)
|
||||
/* XXX shadow warnings in outer-more namespaces */
|
||||
shadow_warning (SW_GLOBAL, false,
|
||||
shadow_warning (SW_GLOBAL,
|
||||
IDENTIFIER_POINTER (name), oldglobal);
|
||||
}
|
||||
}
|
||||
|
@ -6000,10 +6000,16 @@ reorder_blocks_1 (insns, current_block, p_block_stack)
|
||||
|
||||
BLOCK_SUBBLOCKS (block) = 0;
|
||||
TREE_ASM_WRITTEN (block) = 1;
|
||||
BLOCK_SUPERCONTEXT (block) = current_block;
|
||||
BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
|
||||
BLOCK_SUBBLOCKS (current_block) = block;
|
||||
current_block = block;
|
||||
/* When there's only one block for the entire function,
|
||||
current_block == block and we mustn't do this, it
|
||||
will cause infinite recursion. */
|
||||
if (block != current_block)
|
||||
{
|
||||
BLOCK_SUPERCONTEXT (block) = current_block;
|
||||
BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
|
||||
BLOCK_SUBBLOCKS (current_block) = block;
|
||||
current_block = block;
|
||||
}
|
||||
VARRAY_PUSH_TREE (*p_block_stack, block);
|
||||
}
|
||||
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
|
||||
|
@ -5298,8 +5298,8 @@ build_protocol_reference (p)
|
||||
objc_protocol_template),
|
||||
NULL_TREE));
|
||||
|
||||
if (IDENTIFIER_GLOBAL_VALUE (ident))
|
||||
decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
|
||||
if (identifier_global_value (ident))
|
||||
decl = identifier_global_value (ident); /* Set by pushdecl. */
|
||||
else
|
||||
{
|
||||
decl = build_decl (VAR_DECL, ident, ptype);
|
||||
|
@ -1,3 +1,11 @@
|
||||
2003-04-10 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* gcc.c-torture/execute/builtin-noret-2.c: New.
|
||||
* gcc.c-torture/execute/builtin-noret-2.x: New.
|
||||
XFAIL builtin-noret-2.c at -O1 and above.
|
||||
* gcc.dg/redecl.c: New.
|
||||
* gcc.dg/Wshadow-1.c: Update error regexps.
|
||||
|
||||
2003-04-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/abi/bitfield10.C: New test.
|
||||
|
84
gcc/testsuite/gcc.c-torture/execute/builtin-noret-2.c
Normal file
84
gcc/testsuite/gcc.c-torture/execute/builtin-noret-2.c
Normal file
@ -0,0 +1,84 @@
|
||||
/* Test for builtin noreturn attributes when the visible declarations
|
||||
are function-local. Doesn't presently work. Modified from
|
||||
builtin-noret-1.c by Zack Weinberg <zack@codesourcery.com>. */
|
||||
|
||||
extern void tabort (void);
|
||||
extern void texit (void);
|
||||
extern void t_exit (void);
|
||||
extern void t_Exit (void);
|
||||
|
||||
extern void link_failure (void);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
volatile int i = 0;
|
||||
/* The real test here is that the program links. */
|
||||
if (i)
|
||||
tabort ();
|
||||
if (i)
|
||||
texit ();
|
||||
if (i)
|
||||
t_exit ();
|
||||
if (i)
|
||||
t_Exit ();
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void
|
||||
tabort (void)
|
||||
{
|
||||
extern void abort (void);
|
||||
abort ();
|
||||
link_failure ();
|
||||
}
|
||||
|
||||
void
|
||||
texit (void)
|
||||
{
|
||||
extern void exit (int);
|
||||
exit (1);
|
||||
link_failure ();
|
||||
}
|
||||
|
||||
void
|
||||
t_exit (void)
|
||||
{
|
||||
extern void _exit (int);
|
||||
_exit (1);
|
||||
link_failure ();
|
||||
}
|
||||
|
||||
/* Some non-Unix libcs might not have _exit. This version should never
|
||||
get called. */
|
||||
static void
|
||||
_exit (int i)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
t_Exit (void)
|
||||
{
|
||||
extern void _Exit (int);
|
||||
_Exit (1);
|
||||
link_failure ();
|
||||
}
|
||||
|
||||
/* Some libcs might not have _Exit. This version should never get called. */
|
||||
static void
|
||||
_Exit (int i)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* When optimizing, no calls to link_failure should remain. In any case,
|
||||
link_failure should not be called. */
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
void
|
||||
link_failure (void)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
#endif
|
12
gcc/testsuite/gcc.c-torture/execute/builtin-noret-2.x
Normal file
12
gcc/testsuite/gcc.c-torture/execute/builtin-noret-2.x
Normal file
@ -0,0 +1,12 @@
|
||||
# This test fails at -O1 and higher.
|
||||
set torture_eval_before_compile {
|
||||
global compiler_conditional_xfail_data
|
||||
set compiler_conditional_xfail_data {
|
||||
"Fails at all optimization levels but -O0, see PR10375." \
|
||||
{ "*-*-*" } \
|
||||
{ "-O*" } \
|
||||
{ "-O0" }
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
@ -10,10 +10,10 @@ void foo (double decl1) /* { dg-warning "shadows a global decl" } */
|
||||
{
|
||||
}
|
||||
|
||||
void foo1 (int d) /* { dg-warning "shadowed declaration" } */
|
||||
void foo1 (int d) /* { dg-warning "previous declaration" } */
|
||||
{
|
||||
double d; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "shadows a parameter" "" { target *-*-* } 15 } */
|
||||
/* { dg-error "redeclared as different" "" { target *-*-* } 15 } */
|
||||
}
|
||||
|
||||
void foo2 (int d) /* { dg-warning "shadowed declaration" } */
|
||||
|
101
gcc/testsuite/gcc.dg/redecl-1.c
Normal file
101
gcc/testsuite/gcc.dg/redecl-1.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* Test for various situations where a new declaration of an
|
||||
identifier conflicts with an earlier declaration which isn't in the
|
||||
same scope. These are all undefined behavior per C89 sections
|
||||
6.1.2.2p7, 6.1.2.6p2, and 6.3.2.2p2/footnote 38 (C99 6.2.2p7 and
|
||||
6.2.7p2 - implicit declarations are invalid in C99). */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c89 -pedantic -Wall -Wno-unused" } */
|
||||
|
||||
/* Extern at function scope, clashing with extern at file scope */
|
||||
|
||||
extern int foo1; /* { dg-error "previous" } */
|
||||
extern int bar1(int); /* { dg-error "previous" } */
|
||||
|
||||
void test1(void)
|
||||
{
|
||||
extern double foo1; /* { dg-error "conflict" } */
|
||||
extern double bar1(double); /* { dg-error "conflict" } */
|
||||
}
|
||||
|
||||
/* Extern at file scope, clashing with extern at function scope */
|
||||
|
||||
void test2(void)
|
||||
{
|
||||
extern double foo2; /* { dg-error "previous" } */
|
||||
extern double bar2(double); /* { dg-error "previous" } */
|
||||
}
|
||||
|
||||
extern int foo2; /* { dg-error "conflict" } */
|
||||
extern int bar2(int); /* { dg-error "conflict" } */
|
||||
|
||||
/* Extern at function scope, clashing with extern at earlier function
|
||||
scope. Also, don't be fooled by a typedef at file scope. */
|
||||
|
||||
typedef float baz3; /* { dg-bogus } */
|
||||
|
||||
void prime3(void)
|
||||
{
|
||||
extern int foo3; /* { dg-error "previous" } */
|
||||
extern int bar3(int); /* { dg-error "previous" } */
|
||||
extern int baz3; /* { dg-error "previous" } */
|
||||
}
|
||||
|
||||
void test3(void)
|
||||
{
|
||||
extern double foo3; /* { dg-error "conflict" } */
|
||||
extern double bar3(double); /* { dg-error "conflict" } */
|
||||
extern double baz3; /* { dg-error "conflict" } */
|
||||
}
|
||||
|
||||
/* Extern at function scope, clashing with previous implicit decl. */
|
||||
|
||||
void prime4(void)
|
||||
{
|
||||
bar4(); /* { dg-error "previous|implicit" } */
|
||||
}
|
||||
|
||||
void test4(void)
|
||||
{
|
||||
extern double bar4(double); /* { dg-error "conflict" } */
|
||||
}
|
||||
|
||||
/* Implicit decl, clashing with extern at previous function scope. */
|
||||
|
||||
void prime5(void)
|
||||
{
|
||||
extern double bar5(double); /* { dg-error "previous" "" { xfail *-*-* } } */
|
||||
}
|
||||
|
||||
void test5(void)
|
||||
{
|
||||
bar5(1); /* { dg-error "implicit" } */
|
||||
}
|
||||
|
||||
/* Extern then static, both at file scope. */
|
||||
|
||||
extern int test6(int); /* { dg-warning "previous" "" { xfail *-*-* } } */
|
||||
static int test6(int x)
|
||||
{ return x; } /* { dg-warning "follows non-static" } */
|
||||
|
||||
|
||||
/* Extern then static, extern at previous function scope. */
|
||||
|
||||
void prime7(void)
|
||||
{
|
||||
extern int test7(int); /* { dg-warning "previous" "" { xfail *-*-* } } */
|
||||
}
|
||||
|
||||
static int test7(int x)
|
||||
{ return x; } /* { dg-warning "follows non-static" } */
|
||||
|
||||
/* Implicit decl then static. */
|
||||
|
||||
void prime8(void)
|
||||
{
|
||||
test8(); /* { dg-warning "previous" "" { xfail *-*-* } } */
|
||||
/* { dg-warning "implicit" "" { target *-*-* } 96 } */
|
||||
}
|
||||
|
||||
static int test8(int x)
|
||||
{ return x; } /* { dg-warning "follows non-static" } */
|
Loading…
Reference in New Issue
Block a user