#include "defaults.h"
#include "ggc.h"
#include "tm_p.h"
-
-#if USE_CPPLIB
#include "cpplib.h"
-extern cpp_reader parse_in;
-#endif
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
#ifndef WINT_TYPE
#define WINT_TYPE "unsigned int"
#endif
-\f
-/* Do GC. */
-int ggc_p = 1;
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "int" \
+ : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "long int" \
+ : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "unsigned int" \
+ : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "long unsigned int" \
+ : "long long unsigned int"))
+#endif
+\f
/* Nonzero if we have seen an invalid cross reference
to a struct, union, or enum, but not yet printed the message. */
int flag_no_asm;
-/* Nonzero means don't recognize any builtin functions. */
-
-int flag_no_builtin;
-
-/* Nonzero means don't recognize the non-ANSI builtin functions.
- -ansi sets this. */
-
-int flag_no_nonansi_builtin;
-
/* Nonzero means do some things the same way PCC does. */
int flag_traditional;
-/* Nonzero means enable C89 Amendment 1 features, other than digraphs. */
+/* Nonzero means enable C89 Amendment 1 features. */
int flag_isoc94 = 0;
int flag_isoc99 = 0;
-/* Nonzero means accept digraphs. */
-
-int flag_digraphs = 1;
-
/* Nonzero means that we have builtin functions, and main is an int */
int flag_hosted = 1;
int warn_bad_function_cast;
-/* Warn about functions which might be candidates for attribute noreturn. */
+/* Warn about functions which might be candidates for format attributes. */
-int warn_missing_noreturn;
+int warn_missing_format_attribute;
/* Warn about traditional constructs whose meanings changed in ANSI C. */
char **argv;
{
int strings_processed;
+ const char *option_value = NULL;
char *p = argv[0];
-#if USE_CPPLIB
- strings_processed = cpp_handle_option (&parse_in, argc, argv);
-#else
- strings_processed = 0;
-#endif /* ! USE_CPPLIB */
- if (!strcmp (p, "-lang-objc"))
- c_language = clk_objective_c;
- else if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
+ strings_processed = cpp_handle_option (parse_in, argc, argv);
+
+ if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
{
flag_traditional = 1;
flag_writable_strings = 1;
- flag_digraphs = 0;
}
else if (!strcmp (p, "-fallow-single-precision"))
flag_allow_single_precision = 1;
{
flag_traditional = 0;
flag_writable_strings = 0;
- flag_digraphs = 1;
}
else if (!strncmp (p, "-std=", 5))
{
|| !strcmp (argstart, "c89"))
{
iso_1990:
- flag_digraphs = 0;
flag_isoc94 = 0;
- iso_1990_digraphs:
+ iso_1994:
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
}
else if (!strcmp (argstart, "iso9899:199409"))
{
- flag_digraphs = 1;
flag_isoc94 = 1;
- goto iso_1990_digraphs;
+ goto iso_1994;
}
else if (!strcmp (argstart, "iso9899:199x")
|| !strcmp (argstart, "iso9899:1999")
flag_no_nonansi_builtin = 1;
flag_noniso_default_format_attributes = 0;
flag_isoc99 = 1;
- flag_digraphs = 1;
flag_isoc94 = 1;
}
else if (!strcmp (argstart, "gnu89"))
flag_no_nonansi_builtin = 0;
flag_noniso_default_format_attributes = 1;
flag_isoc99 = 0;
- flag_digraphs = 1;
flag_isoc94 = 0;
}
else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
flag_no_nonansi_builtin = 0;
flag_noniso_default_format_attributes = 1;
flag_isoc99 = 1;
- flag_digraphs = 1;
flag_isoc94 = 1;
}
else
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
flag_no_builtin = 1;
+ else if ((option_value
+ = skip_leading_substring (p, "-fdump-translation-unit-")))
+ {
+ if (p[22] == '\0')
+ error ("no file specified with -fdump-translation-unit");
+ else
+ flag_dump_translation_unit = option_value;
+ }
else if (!strcmp (p, "-ansi"))
goto iso_1990;
else if (!strcmp (p, "-Werror-implicit-function-declaration"))
warn_missing_noreturn = 1;
else if (!strcmp (p, "-Wno-missing-noreturn"))
warn_missing_noreturn = 0;
+ else if (!strcmp (p, "-Wmissing-format-attribute"))
+ warn_missing_format_attribute = 1;
+ else if (!strcmp (p, "-Wno-missing-format-attribute"))
+ warn_missing_format_attribute = 0;
else if (!strcmp (p, "-Wpointer-arith"))
warn_pointer_arith = 1;
else if (!strcmp (p, "-Wno-pointer-arith"))
warn_return_type = 1;
else if (!strcmp (p, "-Wno-return-type"))
warn_return_type = 0;
+ else if (!strcmp (p, "-Wsequence-point"))
+ warn_sequence_point = 1;
+ else if (!strcmp (p, "-Wno-sequence-point"))
+ warn_sequence_point = 0;
else if (!strcmp (p, "-Wcomment"))
; /* cpp handles this one. */
else if (!strcmp (p, "-Wno-comment"))
warn_format = 1;
warn_char_subscripts = 1;
warn_parentheses = 1;
+ warn_sequence_point = 1;
warn_missing_braces = 1;
/* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn
it off only if it's not explicit. */
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
}
+ /* We used to warn about unused variables in expand_end_bindings,
+ i.e. while generating RTL. But in function-at-a-time mode we may
+ choose to never expand a function at all (e.g. auto inlining), so
+ we do this explicitly now. */
+ warn_about_unused_variables (getdecls ());
+
/* If there were any declarations or structure tags in that level,
or if this level is a function body,
create a BLOCK to record them for the life of this function. */
{
register unsigned olddecl_uid = DECL_UID (olddecl);
- bcopy ((char *) newdecl + sizeof (struct tree_common),
- (char *) olddecl + sizeof (struct tree_common),
- sizeof (struct tree_decl) - sizeof (struct tree_common));
+ memcpy ((char *) olddecl + sizeof (struct tree_common),
+ (char *) newdecl + sizeof (struct tree_common),
+ sizeof (struct tree_decl) - sizeof (struct tree_common));
DECL_UID (olddecl) = olddecl_uid;
}
wint_type_node =
TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
+ intmax_type_node =
+ TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
+ uintmax_type_node =
+ TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
+
boolean_type_node = integer_type_node;
boolean_true_node = integer_one_node;
boolean_false_node = integer_zero_node;
+ /* With GCC, C99's _Bool is always of size 1. */
+ c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+ TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
+ TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
+ TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
+ TYPE_PRECISION (c_bool_type_node) = 1;
+ pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
+ c_bool_type_node));
+ c_bool_false_node = build_int_2 (0, 0);
+ TREE_TYPE (c_bool_false_node) = c_bool_type_node;
+ c_bool_true_node = build_int_2 (1, 0);
+ TREE_TYPE (c_bool_true_node) = c_bool_type_node;
+
string_type_node = build_pointer_type (char_type_node);
const_string_type_node
= build_pointer_type (build_type_variant (char_type_node, 1, 0));
= TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
- c_common_nodes_and_builtins (0, flag_no_builtin, flag_no_nonansi_builtin);
+ c_common_nodes_and_builtins ();
endlink = void_list_node;
ptr_ftype_void = build_function_type (ptr_type_node, endlink);
default:
/* Don't allow initializations for incomplete types
except for arrays which might be completed by the initialization. */
- if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
+
+ /* This can happen if the array size is an undefined macro. We already
+ gave a warning, so we don't need another one. */
+ if (TREE_TYPE (decl) == error_mark_node)
+ initialized = 0;
+ else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
{
/* A complete type is ok if size is fixed. */
&& DECL_RTL (tem) == 0
&& !DECL_CONTEXT (tem))
{
- if (COMPLETE_TYPE_P (TREE_TYPE (tem)))
+ if (TREE_TYPE (tem) != error_mark_node
+ && COMPLETE_TYPE_P (TREE_TYPE (tem)))
expand_decl (tem);
else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
&& DECL_INITIAL (tem) != 0)
{
register tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
- char *asmspec = 0;
+ const char *asmspec = 0;
/* If a name was specified, get the string. */
if (asmspec_tree)
if (failure == 1)
error_with_decl (decl, "initializer fails to determine size of `%s'");
- if (failure == 2)
+ else if (failure == 2)
{
if (do_default)
error_with_decl (decl, "array size missing in `%s'");
/* TYPE_MAX_VALUE is always one less than the number of elements
in the array, because we start counting at zero. Therefore,
warn only if the value is less than zero. */
- if (pedantic && TYPE_DOMAIN (type) != 0
- && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+ else if (pedantic && TYPE_DOMAIN (type) != 0
+ && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
error_with_decl (decl, "zero or negative size array `%s'");
layout_decl (decl, 0);
if (TREE_CODE (decl) == VAR_DECL)
{
- if (DECL_SIZE (decl) == 0 && COMPLETE_TYPE_P (TREE_TYPE (decl)))
+ if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node
+ && COMPLETE_TYPE_P (TREE_TYPE (decl)))
layout_decl (decl, 0);
if (DECL_SIZE (decl) == 0
+ /* Don't give an error if we already gave one earlier. */
+ && TREE_TYPE (decl) != error_mark_node
&& (TREE_STATIC (decl)
?
/* A static variable with an incomplete type
else
{
if (asmspec)
- DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+ {
+ DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+ DECL_C_HARD_REGISTER (decl) = 1;
+ }
add_decl_stmt (decl);
}
{
if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
| (1 << (int) RID_SIGNED)
- | (1 << (int) RID_UNSIGNED))))
+ | (1 << (int) RID_UNSIGNED)
+ | (1 << (int) RID_COMPLEX))))
/* Don't warn about typedef foo = bar. */
&& ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
&& ! in_system_header)
if (specbits & 1 << (int) RID_COMPLEX)
{
+ if (pedantic && !flag_isoc99)
+ pedwarn ("ISO C89 does not support complex types");
/* If we just have "complex", it is equivalent to
"complex double", but if any modifiers at all are specified it is
the complex form of TYPE. E.g, "complex short" is
&& ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
| (1 << (int) RID_SIGNED)
| (1 << (int) RID_UNSIGNED))))
- type = complex_double_type_node;
+ {
+ if (pedantic)
+ pedwarn ("ISO C does not support plain `complex' meaning `double complex'");
+ type = complex_double_type_node;
+ }
else if (type == integer_type_node)
- type = complex_integer_type_node;
+ {
+ if (pedantic)
+ pedwarn ("ISO C does not support complex integer types");
+ type = complex_integer_type_node;
+ }
else if (type == float_type_node)
type = complex_float_type_node;
else if (type == double_type_node)
else if (type == long_double_type_node)
type = complex_long_double_type_node;
else
- type = build_complex_type (type);
+ {
+ if (pedantic)
+ pedwarn ("ISO C does not support complex integer types");
+ type = build_complex_type (type);
+ }
}
/* Figure out the type qualifiers for the declaration. There are
}
}
- /* Convert size to index_type, so that if it is a variable
- the computations will be done in the proper mode. */
- itype = fold (build (MINUS_EXPR, index_type,
- convert (index_type, size),
- convert (index_type, size_one_node)));
-
- /* If that overflowed, the array is too big.
- ??? While a size of INT_MAX+1 technically shouldn't cause
- an overflow (because we subtract 1), the overflow is recorded
- during the conversion to index_type, before the subtraction.
- Handling this case seems like an unnecessary complication. */
- if (TREE_OVERFLOW (itype))
+ if (integer_zerop (size))
{
- error ("size of array `%s' is too large", name);
- type = error_mark_node;
- continue;
+ /* A zero-length array cannot be represented with an
+ unsigned index type, which is what we'll get with
+ build_index_type. Create an open-ended range instead. */
+ itype = build_range_type (sizetype, size, NULL_TREE);
+ }
+ else
+ {
+ /* Compute the maximum valid index, that is, size - 1.
+ Do the calculation in index_type, so that if it is
+ a variable the computations will be done in the
+ proper mode. */
+ itype = fold (build (MINUS_EXPR, index_type,
+ convert (index_type, size),
+ convert (index_type, size_one_node)));
+
+ /* If that overflowed, the array is too big.
+ ??? While a size of INT_MAX+1 technically shouldn't
+ cause an overflow (because we subtract 1), the overflow
+ is recorded during the conversion to index_type, before
+ the subtraction. Handling this case seems like an
+ unnecessary complication. */
+ if (TREE_OVERFLOW (itype))
+ {
+ error ("size of array `%s' is too large", name);
+ type = error_mark_node;
+ continue;
+ }
+
+ if (size_varies)
+ itype = variable_size (itype);
+ itype = build_index_type (itype);
}
+ }
+ else if (decl_context == FIELD)
+ {
+ /* ??? Need to check somewhere that this is a structure
+ and not a union, that this field is last, and that
+ this structure has at least one other named member. */
+
+ if (pedantic && !flag_isoc99 && !in_system_header)
+ pedwarn ("ISO C89 does not support flexible array members");
- if (size_varies)
- itype = variable_size (itype);
- itype = build_index_type (itype);
+ /* ISO C99 Flexible array members are effectively identical
+ to GCC's zero-length array extension. */
+ itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
}
#if 0
/* Type qualifiers before the return type of the function
qualify the return type, not the function type. */
if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ {
+ /* Type qualifiers on a function return type are normally
+ permitted by the standard but have no effect, so give a
+ warning at -W. Qualifiers on a void return type have
+ meaning as a GNU extension, and are banned on function
+ definitions in ISO C. FIXME: strictly we shouldn't
+ pedwarn for qualified void return types except on function
+ definitions, but not doing so could lead to the undesirable
+ state of a "volatile void" function return type not being
+ warned about, and a use of the function being compiled
+ with GNU semantics, with no diagnostics under -pedantic. */
+ if (VOID_TYPE_P (type) && pedantic && !in_system_header)
+ pedwarn ("ISO C forbids qualified void function return type");
+ else if (extra_warnings
+ && !(VOID_TYPE_P (type)
+ && type_quals == TYPE_QUAL_VOLATILE))
+ warning ("type qualifiers ignored on function return type");
+
+ type = c_build_qualified_type (type, type_quals);
+ }
type_quals = TYPE_UNQUALIFIED;
type = build_function_type (type, arg_types);
controlled separately by its own initializer. */
if (type != 0 && typedef_type != 0
- && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type)
- && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0)
+ && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
+ && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
{
type = build_array_type (TREE_TYPE (type), 0);
if (size_varies)
if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ISO C forbids qualified function types");
- if (pedantic
- && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
- && TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
- && ! DECL_IN_SYSTEM_HEADER (decl))
- pedwarn ("ISO C forbids qualified void function return type");
-
/* GNU C interprets a `volatile void' return type to indicate
that the function does not return. */
if ((type_quals & TYPE_QUAL_VOLATILE)
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
&& TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
&& TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
{
error_with_decl (x, "bit-field `%s' has invalid type");
if (DECL_INITIAL (x) && pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
/* Accept an enum that's equivalent to int or unsigned int. */
&& !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (x))
field widths. */
if (DECL_INITIAL (x))
{
+ int max_width;
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node)
+ max_width = CHAR_TYPE_SIZE;
+ else
+ max_width = TYPE_PRECISION (TREE_TYPE (x));
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
error_with_decl (x, "negative width in bit-field `%s'");
- else if (0 < compare_tree_int (DECL_INITIAL (x),
- TYPE_PRECISION (TREE_TYPE (x))))
+ else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
pedwarn_with_decl (x, "width of `%s' exceeds its type");
else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
error_with_decl (x, "zero width for bit-field `%s'");
"`%s' is narrower than values of its type");
DECL_SIZE (x) = bitsize_int (width);
- DECL_BIT_FIELD (x) = DECL_C_BIT_FIELD (x) = 1;
+ DECL_BIT_FIELD (x) = 1;
+ SET_DECL_C_BIT_FIELD (x);
if (width == 0)
{
tree decl;
for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl))
{
- if (TREE_TYPE (decl) == t
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
&& TREE_CODE (decl) != TYPE_DECL)
{
layout_decl (decl, 0);
function. For a nested function, this value is used in
pop_c_function_context and then reset via pop_function_context. */
current_function_decl = NULL;
+ c_function_name_declared_p = 0;
}
}
tree fndecl;
int nested_p;
{
+ /* There's no reason to do any of the work here if we're only doing
+ semantic analysis; this code just generates RTL. */
+ if (flag_syntax_only)
+ return;
+
/* Squirrel away our current state. */
if (nested_p)
push_function_context ();
/* Initialize the RTL code for the function. */
current_function_decl = fndecl;
- init_function_start (fndecl, input_filename, lineno);
+ init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
/* This function is being processed in whole-function mode. */
cfun->x_whole_function_mode_p = 1;
immediate_size_expand = 0;
cfun->x_dont_save_pending_sizes_p = 1;
+ /* If this is a varargs function, inform function.c. */
+ if (c_function_varargs)
+ mark_varargs ();
+
/* Set up parameters and prepare for return, for the function. */
expand_function_start (fndecl, 0);
&& DECL_CONTEXT (fndecl) == NULL_TREE)
expand_main_function ();
- /* If this is a varargs function, inform function.c. */
- if (c_function_varargs)
- mark_varargs ();
-
/* Generate the RTL for this function. */
expand_stmt (DECL_SAVED_TREE (fndecl));
/* Allow the body of the function to be garbage collected. */
/* Generate rtl for function exit. */
expand_function_end (input_filename, lineno, 0);
- /* So we can tell if jump_optimize sets it to 1. */
- can_reach_end = 0;
-
/* If this is a nested function, protect the local variables in the stack
above us from being collected while we're compiling this function. */
if (nested_p)
if (nested_p)
ggc_pop_context ();
- current_function_returns_null |= can_reach_end;
-
- if (warn_missing_noreturn
- && !TREE_THIS_VOLATILE (fndecl)
- && !current_function_returns_null
- && !current_function_returns_value)
- warning ("function might be possible candidate for attribute `noreturn'");
-
- if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
- warning ("`noreturn' function does return");
- else if (warn_return_type && can_reach_end
- && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
- /* If this function returns non-void and control can drop through,
- complain. */
- warning ("control reaches end of non-void function");
/* With just -W, complain only if function returns both with
and without a value. */
- else if (extra_warnings
- && current_function_returns_value && current_function_returns_null)
+ if (extra_warnings
+ && current_function_returns_value
+ && current_function_returns_null)
warning ("this function may return with or without a value");
/* If requested, warn about function definitions where the function will
}
\f
+/* Check the declarations given in a for-loop for satisfying the C99
+ constraints. */
+void
+check_for_loop_decls ()
+{
+ tree t;
+
+ if (!flag_isoc99)
+ {
+ /* If we get here, declarations have been used in a for loop without
+ the C99 for loop scope. This doesn't make much sense, so don't
+ allow it. */
+ error ("`for' loop initial declaration used outside C99 mode");
+ return;
+ }
+ /* C99 subclause 6.8.5 paragraph 3:
+
+ [#3] The declaration part of a for statement shall only
+ declare identifiers for objects having storage class auto or
+ register.
+
+ It isn't clear whether, in this sentence, "identifiers" binds to
+ "shall only declare" or to "objects" - that is, whether all identifiers
+ declared must be identifiers for objects, or whether the restriction
+ only applies to those that are. (A question on this in comp.std.c
+ in November 2000 received no answer.) We implement the strictest
+ interpretation, to avoid creating an extension which later causes
+ problems. */
+
+ for (t = gettags (); t; t = TREE_CHAIN (t))
+ {
+ if (TREE_PURPOSE (t) != 0)
+ error ("`%s %s' declared in `for' loop initial declaration",
+ (TREE_CODE (TREE_VALUE (t)) == RECORD_TYPE ? "struct"
+ : TREE_CODE (TREE_VALUE (t)) == UNION_TYPE ? "union"
+ : "enum"),
+ IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+ }
+ for (t = getdecls (); t; t = TREE_CHAIN (t))
+ {
+ if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
+ error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
+ else if (TREE_STATIC (t))
+ error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
+ else if (DECL_EXTERNAL (t))
+ error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
+ }
+}
+\f
/* Save and restore the variables in this file and elsewhere
that keep track of the progress of compilation of the current function.
Used for nested functions. */
return;
ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl));
- bcopy ((char *)DECL_LANG_SPECIFIC (decl), (char *)ld,
- sizeof (struct lang_decl));
+ memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl),
+ sizeof (struct lang_decl));
DECL_LANG_SPECIFIC (decl) = ld;
}
-/* Mark ARG for GC. */
-
-void
-lang_mark_false_label_stack (arg)
- struct label_node *arg;
-{
- /* C doesn't use false_label_stack. It better be NULL. */
- if (arg != NULL)
- abort ();
-}
-
/* Mark the language specific bits in T for GC. */
void