aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2009-06-19 15:29:18 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2009-06-19 15:29:18 +0000
commitdc491a250a946a50bdea3813e9f1f67d368e348b (patch)
tree0dea9b2fb4eca6aa396f8ba7b9c2513061e504ae
parent88eeff6f5a1347dc09de33c26a68648c4dea7f80 (diff)
downloadgcc-dc491a250a946a50bdea3813e9f1f67d368e348b.zip
gcc-dc491a250a946a50bdea3813e9f1f67d368e348b.tar.gz
gcc-dc491a250a946a50bdea3813e9f1f67d368e348b.tar.bz2
dse.c (struct store_info): Rename bitmap field to bmap.
./: * dse.c (struct store_info): Rename bitmap field to bmap. Change all uses. * c-decl.c (in_struct, struct_types): Remove. (struct c_binding): Add in_struct field. (c_binding_ptr): Define type, along with VEC. (struct c_struct_parse_info): Define. (struct_parse_info): New static variable. (bind): Initialize in_struct field. (start_struct): Remove enclosing_in_struct and enclosing_struct_types parameters. Add enclosing_struct_parse_info parameter. Change all callers. Set struct_parse_info rather than in_struct and struct_types. (grokfield): If -Wc++-compat and there is a symbol binding for the field name, set the in_struct flag and push it on the struct_parse_info->fields vector. (warn_cxx_compat_finish_struct): New static function. (finish_struct): Remove enclosing_in_struct and enclosing_struct_types parameters. Add enclosing_struct_parse_info parameter. Change all callers. Don't set C_TYPE_DEFINED_IN_STRUCT here. Call warn_cxx_compat_finish_struct. Free struct_parse_info and set to parameter. Only push on struct_types if warn_cxx_compat. (finish_enum): Only push on struct_types if warn_cxx_compat. (declspecs_add_type): Add loc parameter. Change all callers. Change all error calls to error_at. Pass loc, not input_location, to pedwarn calls. Warn if -Wc++-compat and a typedef name is defined in a struct. If -Wc++-compat and parsing a struct, record that a typedef name was used. * c-parser.c (c_parser_declspecs): Get location to pass to declspecs_add_type. (c_parser_struct_or_union_specifier): Update calls to start_struct and finish_struct. * c-tree.h (struct c_struct_parse_info): Declare. (finish_struct, start_struct): Update declarations. (declspecs_add_type): Update declaration. objc/: * objc-act.c (objc_in_struct, objc_struct_types): Remove. (objc_struct_info): New static variable. (objc_start_struct): Pass &objc_struct_info, not &objc_in_struct and &objc_struct_types, to start_struct. (objc_finish_struct): Likewise for finish_struct. objcp/: * objcp-decl.h (start_struct): Remove in_struct and struct_types parameters. Add struct_info parameter. (finish_struct): Likewise. testsuite/: * gcc.dg/Wcxx-compat-15.c: New testcase. From-SVN: r148709
-rw-r--r--gcc/ChangeLog39
-rw-r--r--gcc/c-decl.c668
-rw-r--r--gcc/c-parser.c22
-rw-r--r--gcc/c-tree.h10
-rw-r--r--gcc/dse.c16
-rw-r--r--gcc/objc/ChangeLog8
-rw-r--r--gcc/objc/objc-act.c8
-rw-r--r--gcc/objcp/ChangeLog6
-rw-r--r--gcc/objcp/objcp-decl.h4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-15.c33
11 files changed, 558 insertions, 260 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 37a3629..c6a39f1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,44 @@
2009-06-19 Ian Lance Taylor <iant@google.com>
+ * dse.c (struct store_info): Rename bitmap field to bmap. Change
+ all uses.
+
+ * c-decl.c (in_struct, struct_types): Remove.
+ (struct c_binding): Add in_struct field.
+ (c_binding_ptr): Define type, along with VEC.
+ (struct c_struct_parse_info): Define.
+ (struct_parse_info): New static variable.
+ (bind): Initialize in_struct field.
+ (start_struct): Remove enclosing_in_struct and
+ enclosing_struct_types parameters. Add
+ enclosing_struct_parse_info parameter. Change all callers. Set
+ struct_parse_info rather than in_struct and struct_types.
+ (grokfield): If -Wc++-compat and there is a symbol binding for the
+ field name, set the in_struct flag and push it on the
+ struct_parse_info->fields vector.
+ (warn_cxx_compat_finish_struct): New static function.
+ (finish_struct): Remove enclosing_in_struct and
+ enclosing_struct_types parameters. Add
+ enclosing_struct_parse_info parameter. Change all callers. Don't
+ set C_TYPE_DEFINED_IN_STRUCT here. Call
+ warn_cxx_compat_finish_struct. Free struct_parse_info and set to
+ parameter. Only push on struct_types if warn_cxx_compat.
+ (finish_enum): Only push on struct_types if warn_cxx_compat.
+ (declspecs_add_type): Add loc parameter. Change all callers.
+ Change all error calls to error_at. Pass loc, not input_location,
+ to pedwarn calls. Warn if -Wc++-compat and a typedef name is
+ defined in a struct. If -Wc++-compat and parsing a struct, record
+ that a typedef name was used.
+ * c-parser.c (c_parser_declspecs): Get location to pass to
+ declspecs_add_type.
+ (c_parser_struct_or_union_specifier): Update calls to start_struct
+ and finish_struct.
+ * c-tree.h (struct c_struct_parse_info): Declare.
+ (finish_struct, start_struct): Update declarations.
+ (declspecs_add_type): Update declaration.
+
+2009-06-19 Ian Lance Taylor <iant@google.com>
+
* c-decl.c (grokdeclarator): If -Wc++-compat, warn about a global
variable with an anonymous type.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 57cbd28..57cf389 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -126,15 +126,6 @@ static GTY(()) struct stmt_tree_s c_stmt_tree;
tree c_break_label;
tree c_cont_label;
-/* True if we are currently parsing the fields of a struct or
- union. */
-
-static bool in_struct;
-
-/* A list of types defined in the current struct or union. */
-
-static VEC(tree,heap) *struct_types;
-
/* Linked list of TRANSLATION_UNIT_DECLS for the translation units
included in this invocation. Note that the current translation
unit is not included in this list. */
@@ -223,7 +214,7 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
BOOL_BITFIELD invisible : 1; /* normal lookup should ignore this binding */
BOOL_BITFIELD nested : 1; /* do not set DECL_CONTEXT when popping */
BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */
- /* one free bit */
+ BOOL_BITFIELD in_struct : 1; /* currently defined as struct field */
location_t locus; /* location for nested bindings */
};
#define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
@@ -513,6 +504,34 @@ static bool keep_next_level_flag;
static bool next_is_function_body;
+/* A VEC of pointers to c_binding structures. */
+
+typedef struct c_binding *c_binding_ptr;
+DEF_VEC_P(c_binding_ptr);
+DEF_VEC_ALLOC_P(c_binding_ptr,heap);
+
+/* Information that we keep for a struct or union while it is being
+ parsed. */
+
+struct c_struct_parse_info
+{
+ /* If warn_cxx_compat, a list of types defined within this
+ struct. */
+ VEC(tree,heap) *struct_types;
+ /* If warn_cxx_compat, a list of field names which have bindings,
+ and which are defined in this struct, but which are not defined
+ in any enclosing struct. This is used to clear the in_struct
+ field of the c_bindings structure. */
+ VEC(c_binding_ptr,heap) *fields;
+ /* If warn_cxx_compat, a list of typedef names used when defining
+ fields in this struct. */
+ VEC(tree,heap) *typedefs_seen;
+};
+
+/* Information for the struct or union currently being parsed, or
+ NULL if not parsing a struct or union. */
+static struct c_struct_parse_info *struct_parse_info;
+
/* Forward declarations. */
static tree lookup_name_in_scope (tree, struct c_scope *);
static tree c_make_fname_decl (location_t, tree, int);
@@ -588,6 +607,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
b->invisible = invisible;
b->nested = nested;
b->inner_comp = 0;
+ b->in_struct = 0;
b->locus = locus;
b->u.type = NULL;
@@ -6289,16 +6309,14 @@ xref_tag (enum tree_code code, tree name)
LOC is the location of the struct's definition.
CODE says which kind of tag NAME ought to be.
- This stores the current value of the file static IN_STRUCT in
- *ENCLOSING_IN_STRUCT, and sets IN_STRUCT to true. Similarly, this
- sets STRUCT_TYPES in *ENCLOSING_STRUCT_TYPES, and sets STRUCT_TYPES
- to an empty vector. The old values are restored in
- finish_struct. */
+ This stores the current value of the file static STRUCT_PARSE_INFO
+ in *ENCLOSING_STRUCT_PARSE_INFO, and points STRUCT_PARSE_INFO at a
+ new c_struct_parse_info structure. The old value of
+ STRUCT_PARSE_INFO is restored in finish_struct. */
tree
start_struct (location_t loc, enum tree_code code, tree name,
- bool *enclosing_in_struct,
- VEC(tree,heap) **enclosing_struct_types)
+ struct c_struct_parse_info **enclosing_struct_parse_info)
{
/* If there is already a tag defined at this scope
(as a forward reference), just return it. */
@@ -6346,10 +6364,11 @@ start_struct (location_t loc, enum tree_code code, tree name,
C_TYPE_BEING_DEFINED (ref) = 1;
TYPE_PACKED (ref) = flag_pack_struct;
- *enclosing_in_struct = in_struct;
- *enclosing_struct_types = struct_types;
- in_struct = true;
- struct_types = VEC_alloc(tree, heap, 0);
+ *enclosing_struct_parse_info = struct_parse_info;
+ struct_parse_info = XNEW (struct c_struct_parse_info);
+ struct_parse_info->struct_types = VEC_alloc (tree, heap, 0);
+ struct_parse_info->fields = VEC_alloc (c_binding_ptr, heap, 0);
+ struct_parse_info->typedefs_seen = VEC_alloc (tree, heap, 0);
/* FIXME: This will issue a warning for a use of a type defined
within a statement expr used within sizeof, et. al. This is not
@@ -6437,6 +6456,25 @@ grokfield (location_t loc,
finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
+ if (warn_cxx_compat && DECL_NAME (value) != NULL_TREE)
+ {
+ /* If we currently have a binding for this field, set the
+ in_struct field in the binding, so that we warn about lookups
+ which find it. */
+ struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (value));
+ if (b != NULL)
+ {
+ /* If the in_struct field is not yet set, push it on a list
+ to be cleared when this struct is finished. */
+ if (!b->in_struct)
+ {
+ VEC_safe_push (c_binding_ptr, heap,
+ struct_parse_info->fields, b);
+ b->in_struct = 1;
+ }
+ }
+ }
+
return value;
}
@@ -6497,25 +6535,80 @@ detect_field_duplicates (tree fieldlist)
}
}
+/* Finish up struct info used by -Wc++-compat. */
+
+static void
+warn_cxx_compat_finish_struct (tree fieldlist)
+{
+ unsigned int ix;
+ tree x;
+ struct c_binding *b;
+
+ /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
+ the current struct. We do this now at the end of the struct
+ because the flag is used to issue visibility warnings, and we
+ only want to issue those warnings if the type is referenced
+ outside of the struct declaration. */
+ for (ix = 0; VEC_iterate (tree, struct_parse_info->struct_types, ix, x); ++ix)
+ C_TYPE_DEFINED_IN_STRUCT (x) = 1;
+
+ /* The TYPEDEFS_SEEN field of STRUCT_PARSE_INFO is a list of
+ typedefs used when declaring fields in this struct. If the name
+ of any of the fields is also a typedef name then the struct would
+ not parse in C++, because the C++ lookup rules say that the
+ typedef name would be looked up in the context of the struct, and
+ would thus be the field rather than the typedef. */
+ if (!VEC_empty (tree, struct_parse_info->typedefs_seen)
+ && fieldlist != NULL_TREE)
+ {
+ /* Use a pointer_set using the name of the typedef. We can use
+ a pointer_set because identifiers are interned. */
+ struct pointer_set_t *tset = pointer_set_create ();
+
+ for (ix = 0;
+ VEC_iterate (tree, struct_parse_info->typedefs_seen, ix, x);
+ ++ix)
+ pointer_set_insert (tset, DECL_NAME (x));
+
+ for (x = fieldlist; x != NULL_TREE; x = TREE_CHAIN (x))
+ {
+ if (pointer_set_contains (tset, DECL_NAME (x)))
+ {
+ warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
+ ("using %qD as both field and typedef name is "
+ "invalid in C++"),
+ x);
+ /* FIXME: It would be nice to report the location where
+ the typedef name is used. */
+ }
+ }
+
+ pointer_set_destroy (tset);
+ }
+
+ /* For each field which has a binding and which was not defined in
+ an enclosing struct, clear the in_struct field. */
+ for (ix = 0;
+ VEC_iterate (c_binding_ptr, struct_parse_info->fields, ix, b);
+ ++ix)
+ b->in_struct = 0;
+}
+
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
ATTRIBUTES are attributes to be applied to the structure.
- ENCLOSING_IN_STRUCT is the value of IN_STRUCT, and
- ENCLOSING_STRUCT_TYPES is the value of STRUCT_TYPES, when the
- struct was started. This sets the C_TYPE_DEFINED_IN_STRUCT flag
- for any type defined in the current struct. */
+ ENCLOSING_STRUCT_PARSE_INFO is the value of STRUCT_PARSE_INFO when
+ the struct was started. */
tree
finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
- bool enclosing_in_struct,
- VEC(tree,heap) *enclosing_struct_types)
+ struct c_struct_parse_info *enclosing_struct_parse_info)
{
tree x;
bool toplevel = file_scope == current_scope;
int saw_named_field;
- unsigned int ix;
/* If this type was previously laid out as a forward reference,
make sure we lay it out again. */
@@ -6773,23 +6866,22 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
add_stmt (build_stmt (loc,
DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
- /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
- the current struct. We do this now at the end of the struct
- because the flag is used to issue visibility warnings when using
- -Wc++-compat, and we only want to issue those warnings if the
- type is referenced outside of the struct declaration. */
- for (ix = 0; VEC_iterate (tree, struct_types, ix, x); ++ix)
- C_TYPE_DEFINED_IN_STRUCT (x) = 1;
+ if (warn_cxx_compat)
+ warn_cxx_compat_finish_struct (fieldlist);
- VEC_free (tree, heap, struct_types);
+ VEC_free (tree, heap, struct_parse_info->struct_types);
+ VEC_free (c_binding_ptr, heap, struct_parse_info->fields);
+ VEC_free (tree, heap, struct_parse_info->typedefs_seen);
+ XDELETE (struct_parse_info);
- in_struct = enclosing_in_struct;
- struct_types = enclosing_struct_types;
+ struct_parse_info = enclosing_struct_parse_info;
/* If this struct is defined inside a struct, add it to
- STRUCT_TYPES. */
- if (in_struct && !in_sizeof && !in_typeof && !in_alignof)
- VEC_safe_push (tree, heap, struct_types, t);
+ struct_types. */
+ if (warn_cxx_compat
+ && struct_parse_info != NULL
+ && !in_sizeof && !in_typeof && !in_alignof)
+ VEC_safe_push (tree, heap, struct_parse_info->struct_types, t);
return t;
}
@@ -7003,9 +7095,11 @@ finish_enum (tree enumtype, tree values, tree attributes)
rest_of_type_compilation (enumtype, toplevel);
/* If this enum is defined inside a struct, add it to
- STRUCT_TYPES. */
- if (in_struct && !in_sizeof && !in_typeof && !in_alignof)
- VEC_safe_push (tree, heap, struct_types, enumtype);
+ struct_types. */
+ if (warn_cxx_compat
+ && struct_parse_info != NULL
+ && !in_sizeof && !in_typeof && !in_alignof)
+ VEC_safe_push (tree, heap, struct_parse_info->struct_types, enumtype);
return enumtype;
}
@@ -8267,7 +8361,8 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
returning SPECS. */
struct c_declspecs *
-declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
+declspecs_add_type (location_t loc, struct c_declspecs *specs,
+ struct c_typespec spec)
{
tree type = spec.spec;
specs->non_sc_seen_p = true;
@@ -8284,7 +8379,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
enum rid i = C_RID_CODE (type);
if (specs->type)
{
- error ("two or more data types in declaration specifiers");
+ error_at (loc, "two or more data types in declaration specifiers");
return specs;
}
if ((int) i <= (int) RID_LAST_MODIFIER)
@@ -8296,203 +8391,257 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
case RID_LONG:
if (specs->long_long_p)
{
- error ("%<long long long%> is too long for GCC");
+ error_at (loc, "%<long long long%> is too long for GCC");
break;
}
if (specs->long_p)
{
if (specs->typespec_word == cts_double)
{
- error ("both %<long long%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long long%> and %<double%> in "
+ "declaration specifiers"));
break;
}
- pedwarn_c90 (input_location, OPT_Wlong_long,
+ pedwarn_c90 (loc, OPT_Wlong_long,
"ISO C90 does not support %<long long%>");
specs->long_long_p = 1;
break;
}
if (specs->short_p)
- error ("both %<long%> and %<short%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<short%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
- error ("both %<long%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_bool)
- error ("both %<long%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_char)
- error ("both %<long%> and %<char%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<char%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_float)
- error ("both %<long%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
- error ("both %<long%> and %<_Decimal32%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<_Decimal32%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64)
- error ("both %<long%> and %<_Decimal64%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<_Decimal64%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128)
- error ("both %<long%> and %<_Decimal128%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<_Decimal128%> in "
+ "declaration specifiers"));
else
specs->long_p = true;
break;
case RID_SHORT:
dupe = specs->short_p;
if (specs->long_p)
- error ("both %<long%> and %<short%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<short%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
- error ("both %<short%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_bool)
- error ("both %<short%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_char)
- error ("both %<short%> and %<char%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<char%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_float)
- error ("both %<short%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_double)
- error ("both %<short%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
- error ("both %<short%> and %<_Decimal32%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<_Decimal32%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64)
- error ("both %<short%> and %<_Decimal64%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<_Decimal64%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128)
- error ("both %<short%> and %<_Decimal128%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<_Decimal128%> in "
+ "declaration specifiers"));
else
specs->short_p = true;
break;
case RID_SIGNED:
dupe = specs->signed_p;
if (specs->unsigned_p)
- error ("both %<signed%> and %<unsigned%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<unsigned%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
- error ("both %<signed%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_bool)
- error ("both %<signed%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_float)
- error ("both %<signed%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_double)
- error ("both %<signed%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
- error ("both %<signed%> and %<_Decimal32%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<_Decimal32%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64)
- error ("both %<signed%> and %<_Decimal64%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<_Decimal64%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128)
- error ("both %<signed%> and %<_Decimal128%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<_Decimal128%> in "
+ "declaration specifiers"));
else
specs->signed_p = true;
break;
case RID_UNSIGNED:
dupe = specs->unsigned_p;
if (specs->signed_p)
- error ("both %<signed%> and %<unsigned%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<unsigned%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_void)
- error ("both %<unsigned%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_bool)
- error ("both %<unsigned%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_float)
- error ("both %<unsigned%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_double)
- error ("both %<unsigned%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
- error ("both %<unsigned%> and %<_Decimal32%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<_Decimal32%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64)
- error ("both %<unsigned%> and %<_Decimal64%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<_Decimal64%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128)
- error ("both %<unsigned%> and %<_Decimal128%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<_Decimal128%> in "
+ "declaration specifiers"));
else
specs->unsigned_p = true;
break;
case RID_COMPLEX:
dupe = specs->complex_p;
if (!flag_isoc99 && !in_system_header)
- pedwarn (input_location, OPT_pedantic, "ISO C90 does not support complex types");
+ pedwarn (loc, OPT_pedantic,
+ "ISO C90 does not support complex types");
if (specs->typespec_word == cts_void)
- error ("both %<complex%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_bool)
- error ("both %<complex%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
- error ("both %<complex%> and %<_Decimal32%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Decimal32%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64)
- error ("both %<complex%> and %<_Decimal64%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Decimal64%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128)
- error ("both %<complex%> and %<_Decimal128%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Decimal128%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_fract)
- error ("both %<complex%> and %<_Fract%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Fract%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_accum)
- error ("both %<complex%> and %<_Accum%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Accum%> in "
+ "declaration specifiers"));
else if (specs->saturating_p)
- error ("both %<complex%> and %<_Sat%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Sat%> in "
+ "declaration specifiers"));
else
specs->complex_p = true;
break;
case RID_SAT:
dupe = specs->saturating_p;
- pedwarn (input_location, OPT_pedantic, "ISO C does not support saturating types");
+ pedwarn (loc, OPT_pedantic,
+ "ISO C does not support saturating types");
if (specs->typespec_word == cts_void)
- error ("both %<_Sat%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_bool)
- error ("both %<_Sat%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_char)
- error ("both %<_Sat%> and %<char%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<char%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_int)
- error ("both %<_Sat%> and %<int%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<int%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_float)
- error ("both %<_Sat%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_double)
- error ("both %<_Sat%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
- error ("both %<_Sat%> and %<_Decimal32%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<_Decimal32%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64)
- error ("both %<_Sat%> and %<_Decimal64%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<_Decimal64%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128)
- error ("both %<_Sat%> and %<_Decimal128%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<_Decimal128%> in "
+ "declaration specifiers"));
else if (specs->complex_p)
- error ("both %<_Sat%> and %<complex%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<complex%> in "
+ "declaration specifiers"));
else
specs->saturating_p = true;
break;
@@ -8501,7 +8650,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
}
if (dupe)
- error ("duplicate %qE", type);
+ error_at (loc, "duplicate %qE", type);
return specs;
}
@@ -8511,110 +8660,137 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
"_Decimal64", "_Decimal128", "_Fract" or "_Accum". */
if (specs->typespec_word != cts_none)
{
- error ("two or more data types in declaration specifiers");
+ error_at (loc,
+ "two or more data types in declaration specifiers");
return specs;
}
switch (i)
{
case RID_VOID:
if (specs->long_p)
- error ("both %<long%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->short_p)
- error ("both %<short%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->signed_p)
- error ("both %<signed%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->unsigned_p)
- error ("both %<unsigned%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->complex_p)
- error ("both %<complex%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<void%> in "
+ "declaration specifiers"));
else if (specs->saturating_p)
- error ("both %<_Sat%> and %<void%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<void%> in "
+ "declaration specifiers"));
else
specs->typespec_word = cts_void;
return specs;
case RID_BOOL:
if (specs->long_p)
- error ("both %<long%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->short_p)
- error ("both %<short%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->signed_p)
- error ("both %<signed%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->unsigned_p)
- error ("both %<unsigned%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->complex_p)
- error ("both %<complex%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<complex%> and %<_Bool%> in "
+ "declaration specifiers"));
else if (specs->saturating_p)
- error ("both %<_Sat%> and %<_Bool%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<_Bool%> in "
+ "declaration specifiers"));
else
specs->typespec_word = cts_bool;
return specs;
case RID_CHAR:
if (specs->long_p)
- error ("both %<long%> and %<char%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<char%> in "
+ "declaration specifiers"));
else if (specs->short_p)
- error ("both %<short%> and %<char%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<char%> in "
+ "declaration specifiers"));
else if (specs->saturating_p)
- error ("both %<_Sat%> and %<char%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<char%> in "
+ "declaration specifiers"));
else
specs->typespec_word = cts_char;
return specs;
case RID_INT:
if (specs->saturating_p)
- error ("both %<_Sat%> and %<int%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<int%> in "
+ "declaration specifiers"));
else
specs->typespec_word = cts_int;
return specs;
case RID_FLOAT:
if (specs->long_p)
- error ("both %<long%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->short_p)
- error ("both %<short%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->signed_p)
- error ("both %<signed%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->unsigned_p)
- error ("both %<unsigned%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<float%> in "
+ "declaration specifiers"));
else if (specs->saturating_p)
- error ("both %<_Sat%> and %<float%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<float%> in "
+ "declaration specifiers"));
else
specs->typespec_word = cts_float;
return specs;
case RID_DOUBLE:
if (specs->long_long_p)
- error ("both %<long long%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<long long%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->short_p)
- error ("both %<short%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<short%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->signed_p)
- error ("both %<signed%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<signed%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->unsigned_p)
- error ("both %<unsigned%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<unsigned%> and %<double%> in "
+ "declaration specifiers"));
else if (specs->saturating_p)
- error ("both %<_Sat%> and %<double%> in "
- "declaration specifiers");
+ error_at (loc,
+ ("both %<_Sat%> and %<double%> in "
+ "declaration specifiers"));
else
specs->typespec_word = cts_double;
return specs;
@@ -8630,26 +8806,40 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else
str = "_Decimal128";
if (specs->long_long_p)
- error ("both %<long long%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<long long%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
if (specs->long_p)
- error ("both %<long%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<long%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (specs->short_p)
- error ("both %<short%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<short%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (specs->signed_p)
- error ("both %<signed%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<signed%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (specs->unsigned_p)
- error ("both %<unsigned%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<unsigned%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (specs->complex_p)
- error ("both %<complex%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<complex%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (specs->saturating_p)
- error ("both %<_Sat%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<_Sat%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (i == RID_DFLOAT32)
specs->typespec_word = cts_dfloat32;
else if (i == RID_DFLOAT64)
@@ -8658,8 +8848,10 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
specs->typespec_word = cts_dfloat128;
}
if (!targetm.decimal_float_supported_p ())
- error ("decimal floating point not supported for this target");
- pedwarn (input_location, OPT_pedantic,
+ error_at (loc,
+ ("decimal floating point not supported "
+ "for this target"));
+ pedwarn (loc, OPT_pedantic,
"ISO C does not support decimal floating point");
return specs;
case RID_FRACT:
@@ -8671,16 +8863,19 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else
str = "_Accum";
if (specs->complex_p)
- error ("both %<complex%> and %<%s%> in "
- "declaration specifiers", str);
+ error_at (loc,
+ ("both %<complex%> and %<%s%> in "
+ "declaration specifiers"),
+ str);
else if (i == RID_FRACT)
specs->typespec_word = cts_fract;
else
specs->typespec_word = cts_accum;
}
if (!targetm.fixed_point_supported_p ())
- error ("fixed-point types not supported for this target");
- pedwarn (input_location, OPT_pedantic,
+ error_at (loc,
+ "fixed-point types not supported for this target");
+ pedwarn (loc, OPT_pedantic,
"ISO C does not support fixed-point types");
return specs;
default:
@@ -8698,7 +8893,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
if (specs->type || specs->typespec_word != cts_none
|| specs->long_p || specs->short_p || specs->signed_p
|| specs->unsigned_p || specs->complex_p)
- error ("two or more data types in declaration specifiers");
+ error_at (loc, "two or more data types in declaration specifiers");
else if (TREE_CODE (type) == TYPE_DECL)
{
if (TREE_TYPE (type) == error_mark_node)
@@ -8709,13 +8904,26 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
specs->decl_attr = DECL_ATTRIBUTES (type);
specs->typedef_p = true;
specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
+
+ /* If this typedef name is defined in a struct, then a C++
+ lookup would return a different value. */
+ if (warn_cxx_compat
+ && I_SYMBOL_BINDING (DECL_NAME (type))->in_struct)
+ warning_at (loc, OPT_Wc___compat,
+ "C++ lookup of %qD would return a field, not a type",
+ type);
+
+ /* If we are parsing a struct, record that a struct field
+ used a typedef. */
+ if (warn_cxx_compat && struct_parse_info != NULL)
+ VEC_safe_push (tree, heap, struct_parse_info->typedefs_seen, type);
}
}
else if (TREE_CODE (type) == IDENTIFIER_NODE)
{
tree t = lookup_name (type);
if (!t || TREE_CODE (t) != TYPE_DECL)
- error ("%qE fails to be a typedef or built in type", type);
+ error_at (loc, "%qE fails to be a typedef or built in type", type);
else if (TREE_TYPE (t) == error_mark_node)
;
else
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 2b78c30..0fc1abb 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -1447,6 +1447,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
{
struct c_typespec t;
tree attrs;
+ location_t loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_NAME))
{
tree value = c_parser_peek_token (parser)->value;
@@ -1482,7 +1483,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t.expr = NULL_TREE;
t.expr_const_operands = true;
}
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
continue;
}
if (c_parser_next_token_is (parser, CPP_LESS))
@@ -1498,7 +1499,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
t.expr = NULL_TREE;
t.expr_const_operands = true;
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
continue;
}
gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
@@ -1547,7 +1548,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t.spec = c_parser_peek_token (parser)->value;
t.expr = NULL_TREE;
t.expr_const_operands = true;
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
c_parser_consume_token (parser);
break;
case RID_ENUM:
@@ -1556,7 +1557,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs_ok = true;
seen_type = true;
t = c_parser_enum_specifier (parser);
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
break;
case RID_STRUCT:
case RID_UNION:
@@ -1566,7 +1567,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
seen_type = true;
t = c_parser_struct_or_union_specifier (parser);
invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
break;
case RID_TYPEOF:
/* ??? The old parser rejected typeof after other type
@@ -1577,7 +1578,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs_ok = true;
seen_type = true;
t = c_parser_typeof_specifier (parser);
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
break;
case RID_CONST:
case RID_VOLATILE:
@@ -1815,10 +1816,8 @@ c_parser_struct_or_union_specifier (c_parser *parser)
{
/* Parse a struct or union definition. Start the scope of the
tag before parsing components. */
- bool in_struct;
- VEC(tree,heap) *struct_types;
- tree type = start_struct (struct_loc, code, ident,
- &in_struct, &struct_types);
+ struct c_struct_parse_info *struct_info;
+ tree type = start_struct (struct_loc, code, ident, &struct_info);
tree postfix_attrs;
/* We chain the components in reverse order, then put them in
forward order at the end. Each struct-declaration may
@@ -1908,8 +1907,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
}
postfix_attrs = c_parser_attributes (parser);
ret.spec = finish_struct (struct_loc, type, nreverse (contents),
- chainon (attrs, postfix_attrs),
- in_struct, struct_types);
+ chainon (attrs, postfix_attrs), struct_info);
ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE;
ret.expr_const_operands = true;
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index f565df5..9d3d2f3 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -430,6 +430,7 @@ extern void gen_aux_info_record (tree, int, int, int);
/* in c-decl.c */
struct c_spot_bindings;
+struct c_struct_parse_info;
extern struct obstack parser_obstack;
extern tree c_break_label;
extern tree c_cont_label;
@@ -465,7 +466,8 @@ extern void c_maybe_initialize_eh (void);
extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
extern void finish_function (void);
-extern tree finish_struct (location_t, tree, tree, tree, bool, VEC(tree,heap) *);
+extern tree finish_struct (location_t, tree, tree, tree,
+ struct c_struct_parse_info *);
extern struct c_arg_info *get_parm_info (bool);
extern tree grokfield (location_t, struct c_declarator *,
struct c_declspecs *, tree, tree *);
@@ -487,7 +489,8 @@ extern tree start_enum (location_t, struct c_enum_contents *, tree);
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
tree);
-extern tree start_struct (location_t, enum tree_code, tree, bool *, VEC(tree,heap) **);
+extern tree start_struct (location_t, enum tree_code, tree,
+ struct c_struct_parse_info **);
extern void store_parm_decls (void);
extern void store_parm_decls_from (struct c_arg_info *);
extern tree xref_tag (enum tree_code, tree);
@@ -504,7 +507,8 @@ extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
struct c_declarator *);
extern struct c_declspecs *build_null_declspecs (void);
extern struct c_declspecs *declspecs_add_qual (struct c_declspecs *, tree);
-extern struct c_declspecs *declspecs_add_type (struct c_declspecs *,
+extern struct c_declspecs *declspecs_add_type (location_t,
+ struct c_declspecs *,
struct c_typespec);
extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
diff --git a/gcc/dse.c b/gcc/dse.c
index 534324d..ca227ea 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -244,7 +244,7 @@ struct store_info
{
/* A bitmap with one bit per byte. Cleared bit means the position
is needed. Used if IS_LARGE is false. */
- bitmap bitmap;
+ bitmap bmap;
/* Number of set bits (i.e. unneeded bytes) in BITMAP. If it is
equal to END - BEGIN, the whole store is unused. */
@@ -791,7 +791,7 @@ free_store_info (insn_info_t insn_info)
{
store_info_t next = store_info->next;
if (store_info->is_large)
- BITMAP_FREE (store_info->positions_needed.large.bitmap);
+ BITMAP_FREE (store_info->positions_needed.large.bmap);
if (store_info->cse_base)
pool_free (cse_store_info_pool, store_info);
else
@@ -1213,10 +1213,10 @@ set_position_unneeded (store_info_t s_info, int pos)
{
if (__builtin_expect (s_info->is_large, false))
{
- if (!bitmap_bit_p (s_info->positions_needed.large.bitmap, pos))
+ if (!bitmap_bit_p (s_info->positions_needed.large.bmap, pos))
{
s_info->positions_needed.large.count++;
- bitmap_set_bit (s_info->positions_needed.large.bitmap, pos);
+ bitmap_set_bit (s_info->positions_needed.large.bmap, pos);
}
}
else
@@ -1233,7 +1233,7 @@ set_all_positions_unneeded (store_info_t s_info)
{
int pos, end = s_info->end - s_info->begin;
for (pos = 0; pos < end; pos++)
- bitmap_set_bit (s_info->positions_needed.large.bitmap, pos);
+ bitmap_set_bit (s_info->positions_needed.large.bmap, pos);
s_info->positions_needed.large.count = end;
}
else
@@ -1263,7 +1263,7 @@ all_positions_needed_p (store_info_t s_info, int start, int width)
{
int end = start + width;
while (start < end)
- if (bitmap_bit_p (s_info->positions_needed.large.bitmap, start++))
+ if (bitmap_bit_p (s_info->positions_needed.large.bmap, start++))
return false;
return true;
}
@@ -1605,7 +1605,7 @@ record_store (rtx body, bb_info_t bb_info)
{
store_info->is_large = true;
store_info->positions_needed.large.count = 0;
- store_info->positions_needed.large.bitmap = BITMAP_ALLOC (NULL);
+ store_info->positions_needed.large.bmap = BITMAP_ALLOC (NULL);
}
else
{
@@ -2721,7 +2721,7 @@ dse_step1 (void)
for (s_info = ptr->store_rec; s_info; s_info = s_info->next)
if (s_info->is_large)
{
- BITMAP_FREE (s_info->positions_needed.large.bitmap);
+ BITMAP_FREE (s_info->positions_needed.large.bmap);
s_info->is_large = false;
}
}
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 2fe4b25..426a6a8 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,11 @@
+2009-06-19 Ian Lance Taylor <iant@google.com>
+
+ * objc-act.c (objc_in_struct, objc_struct_types): Remove.
+ (objc_struct_info): New static variable.
+ (objc_start_struct): Pass &objc_struct_info, not &objc_in_struct
+ and &objc_struct_types, to start_struct.
+ (objc_finish_struct): Likewise for finish_struct.
+
2009-06-15 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_start_function): Don't set
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index f114b65..b6a01ed 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -420,8 +420,7 @@ static int generating_instance_variables = 0;
is compiled as part of obj-c++. */
static bool objc_building_struct;
-static bool objc_in_struct ATTRIBUTE_UNUSED;
-static VEC(tree,heap) *objc_struct_types ATTRIBUTE_UNUSED;
+static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
/* Start building a struct for objc. */
@@ -430,8 +429,7 @@ objc_start_struct (tree name)
{
gcc_assert (!objc_building_struct);
objc_building_struct = true;
- return start_struct (input_location, RECORD_TYPE,
- name, &objc_in_struct, &objc_struct_types);
+ return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
}
/* Finish building a struct for objc. */
@@ -442,7 +440,7 @@ objc_finish_struct (tree type, tree fieldlist)
gcc_assert (objc_building_struct);
objc_building_struct = false;
return finish_struct (input_location, type, fieldlist, NULL_TREE,
- objc_in_struct, objc_struct_types);
+ objc_struct_info);
}
/* Some platforms pass small structures through registers versus
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index 45985f8..526830f 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -1,3 +1,9 @@
+2009-06-19 Ian Lance Taylor <iant@google.com>
+
+ * objcp-decl.h (start_struct): Remove in_struct and struct_types
+ parameters. Add struct_info parameter.
+ (finish_struct): Likewise.
+
2009-06-13 Aldy Hernandez <aldyh@redhat.com>
* objcp-decl.h (start_struct): Add location argument.
diff --git a/gcc/objcp/objcp-decl.h b/gcc/objcp/objcp-decl.h
index 07d39ab..50d9828 100644
--- a/gcc/objcp/objcp-decl.h
+++ b/gcc/objcp/objcp-decl.h
@@ -37,9 +37,9 @@ extern tree objcp_end_compound_stmt (tree, int);
invoke the original C++ functions if needed). */
#ifdef OBJCP_REMAP_FUNCTIONS
-#define start_struct(loc, code, name, in_struct, struct_types) \
+#define start_struct(loc, code, name, struct_info) \
objcp_start_struct (loc, code, name)
-#define finish_struct(loc, t, fieldlist, attributes, in_struct, struct_types) \
+#define finish_struct(loc, t, fieldlist, attributes, struct_info) \
objcp_finish_struct (loc, t, fieldlist, attributes)
#define finish_function() \
objcp_finish_function ()
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b68dc7e..db6c860 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2009-06-19 Ian Lance Taylor <iant@google.com>
+ * gcc.dg/Wcxx-compat-15.c: New testcase.
+
+2009-06-19 Ian Lance Taylor <iant@google.com>
+
* gcc.dg/Wcxx-compat-16.c: New testcase.
2009-06-19 Uros Bizjak <ubizjak@gmail.com>
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-15.c b/gcc/testsuite/gcc.dg/Wcxx-compat-15.c
new file mode 100644
index 0000000..82a76ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-15.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+typedef int myint1;
+typedef int myint2;
+typedef int myint3;
+struct s1
+{
+ myint1 myint1; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+ myint2 *myint2; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+ int myint3;
+ struct s2
+ {
+ myint3 f2; /* { dg-warning "C\[+\]\[+\]" } */
+ } f1;
+};
+
+struct s3
+{
+ int myint1;
+ struct s4
+ {
+ int myint1;
+ } f1;
+ struct s5
+ {
+ int myint1;
+ struct s6
+ {
+ myint1 f4; /* { dg-warning "C\[+\]\[+\]" } */
+ } f3;
+ } f2;
+};