From 843bd2fa78007c193692f6382edf3b6b5c2d3a62 Mon Sep 17 00:00:00 2001 From: ian Date: Fri, 19 Jun 2009 15:29:18 +0000 Subject: [PATCH] ./: * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148709 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 39 ++ gcc/c-decl.c | 668 ++++++++++++++++++++++------------ gcc/c-parser.c | 22 +- gcc/c-tree.h | 10 +- gcc/dse.c | 16 +- gcc/objc/ChangeLog | 8 + gcc/objc/objc-act.c | 8 +- gcc/objcp/ChangeLog | 6 + gcc/objcp/objcp-decl.h | 4 +- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/Wcxx-compat-15.c | 33 ++ 11 files changed, 558 insertions(+), 260 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wcxx-compat-15.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 37a3629ff6d..c6a39f15718 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,44 @@ 2009-06-19 Ian Lance Taylor + * 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 + * 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 57cbd283588..57cf389dc73 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 ("% is too long for GCC"); + error_at (loc, "% is too long for GCC"); break; } if (specs->long_p) { if (specs->typespec_word == cts_double) { - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); break; } - pedwarn_c90 (input_location, OPT_Wlong_long, + pedwarn_c90 (loc, OPT_Wlong_long, "ISO C90 does not support %"); specs->long_long_p = 1; break; } if (specs->short_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_void) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_char) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_float) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error ("both % and %<_Decimal32%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat64) - error ("both % and %<_Decimal64%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat128) - error ("both % and %<_Decimal128%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); else specs->long_p = true; break; case RID_SHORT: dupe = specs->short_p; if (specs->long_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_void) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_char) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_float) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_double) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error ("both % and %<_Decimal32%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat64) - error ("both % and %<_Decimal64%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat128) - error ("both % and %<_Decimal128%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); else specs->short_p = true; break; case RID_SIGNED: dupe = specs->signed_p; if (specs->unsigned_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_void) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_float) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_double) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error ("both % and %<_Decimal32%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat64) - error ("both % and %<_Decimal64%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat128) - error ("both % and %<_Decimal128%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); else specs->signed_p = true; break; case RID_UNSIGNED: dupe = specs->unsigned_p; if (specs->signed_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_void) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_float) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_double) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error ("both % and %<_Decimal32%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat64) - error ("both % and %<_Decimal64%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat128) - error ("both % and %<_Decimal128%> in " - "declaration specifiers"); + error_at (loc, + ("both % 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 % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error ("both % and %<_Decimal32%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat64) - error ("both % and %<_Decimal64%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat128) - error ("both % and %<_Decimal128%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_fract) - error ("both % and %<_Fract%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Fract%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_accum) - error ("both % and %<_Accum%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Accum%> in " + "declaration specifiers")); else if (specs->saturating_p) - error ("both % and %<_Sat%> in " - "declaration specifiers"); + error_at (loc, + ("both % 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 % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % 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 % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_int) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_float) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_double) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % 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 % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % 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 % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->short_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->signed_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->unsigned_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->complex_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->saturating_p) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else specs->typespec_word = cts_void; return specs; case RID_BOOL: if (specs->long_p) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->short_p) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->signed_p) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->unsigned_p) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->complex_p) - error ("both % and %<_Bool%> in " - "declaration specifiers"); + error_at (loc, + ("both % 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 % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->short_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->saturating_p) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else specs->typespec_word = cts_char; return specs; case RID_INT: if (specs->saturating_p) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else specs->typespec_word = cts_int; return specs; case RID_FLOAT: if (specs->long_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->short_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->signed_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->unsigned_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->saturating_p) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); else specs->typespec_word = cts_float; return specs; case RID_DOUBLE: if (specs->long_long_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->short_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->signed_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->unsigned_p) - error ("both % and % in " - "declaration specifiers"); + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->saturating_p) - error ("both %<_Sat%> and % in " - "declaration specifiers"); + error_at (loc, + ("both %<_Sat%> and % 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 % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % and %<%s%> in " + "declaration specifiers"), + str); if (specs->long_p) - error ("both % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % and %<%s%> in " + "declaration specifiers"), + str); else if (specs->short_p) - error ("both % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % and %<%s%> in " + "declaration specifiers"), + str); else if (specs->signed_p) - error ("both % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % and %<%s%> in " + "declaration specifiers"), + str); else if (specs->unsigned_p) - error ("both % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % and %<%s%> in " + "declaration specifiers"), + str); else if (specs->complex_p) - error ("both % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % 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 % and %<%s%> in " - "declaration specifiers", str); + error_at (loc, + ("both % 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 2b78c3042fa..0fc1abb5119 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 f565df58f31..9d3d2f30da0 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 534324d0f5b..ca227ea15dd 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 2fe4b25be8c..426a6a8a2f3 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,11 @@ +2009-06-19 Ian Lance Taylor + + * 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 * objc-act.c (objc_start_function): Don't set diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index f114b65ef4a..b6a01ed316b 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 45985f8db0b..526830f588b 100644 --- a/gcc/objcp/ChangeLog +++ b/gcc/objcp/ChangeLog @@ -1,3 +1,9 @@ +2009-06-19 Ian Lance Taylor + + * objcp-decl.h (start_struct): Remove in_struct and struct_types + parameters. Add struct_info parameter. + (finish_struct): Likewise. + 2009-06-13 Aldy Hernandez * objcp-decl.h (start_struct): Add location argument. diff --git a/gcc/objcp/objcp-decl.h b/gcc/objcp/objcp-decl.h index 07d39abaf8f..50d98287662 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 b68dc7e059b..db6c860c175 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2009-06-19 Ian Lance Taylor + * gcc.dg/Wcxx-compat-15.c: New testcase. + +2009-06-19 Ian Lance Taylor + * gcc.dg/Wcxx-compat-16.c: New testcase. 2009-06-19 Uros Bizjak 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 00000000000..82a76ec4d0f --- /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; +}; -- 2.11.0