@@ -2214,6 +2214,9 @@ Enum(strong_eval_order) String(some) Value(1)
EnumValue
Enum(strong_eval_order) String(all) Value(2)
+ftag-compat
+C Var(flag_tag_compat) Init(1)
+
ftemplate-backtrace-limit=
C++ ObjC++ Joined RejectNegative UInteger Var(template_backtrace_limit) Init(10)
Set the maximum number of template instantiation notes for a single warning or error.
@@ -2094,7 +2094,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
given scope. */
if (TREE_CODE (olddecl) == CONST_DECL)
{
- if (flag_isoc2x
+ if ((flag_isoc2x || flag_tag_compat)
&& TYPE_NAME (DECL_CONTEXT (newdecl))
&& DECL_CONTEXT (newdecl) != DECL_CONTEXT (olddecl)
&& TYPE_NAME (DECL_CONTEXT (newdecl)) == TYPE_NAME (DECL_CONTEXT (olddecl)))
@@ -8723,7 +8723,7 @@ start_struct (location_t loc, enum tree_code code, tree name,
/* For C2X, even if we already have a completed definition,
we do not use it. We will check for consistency later. */
- if (flag_isoc2x && ref && TYPE_SIZE (ref))
+ if ((flag_isoc2x || flag_tag_compat) && ref && TYPE_SIZE (ref))
ref = NULL_TREE;
if (ref && TREE_CODE (ref) == code)
@@ -9515,7 +9515,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
}
/* Check for consistency with previous definition */
- if (flag_isoc2x)
+ if (flag_isoc2x || flag_tag_compat)
{
tree vistype = previous_tag (t);
if (vistype
@@ -9534,7 +9534,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
C_TYPE_BEING_DEFINED (t) = 0;
/* Set type canonical based on equivalence class. */
- if (flag_isoc2x)
+ if (flag_isoc2x || flag_tag_compat)
{
if (NULL == c_struct_htab)
c_struct_htab = hash_table<c_struct_hasher>::create_ggc (61);
@@ -9672,7 +9672,7 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name,
if (name != NULL_TREE)
enumtype = lookup_tag (ENUMERAL_TYPE, name, true, &enumloc);
- if (flag_isoc2x && enumtype != NULL_TREE
+ if ((flag_isoc2x || flag_tag_compat) && enumtype != NULL_TREE
&& TREE_CODE (enumtype) == ENUMERAL_TYPE
&& TYPE_VALUES (enumtype) != NULL_TREE)
enumtype = NULL_TREE;
@@ -9941,7 +9941,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
struct_parse_info->struct_types.safe_push (enumtype);
/* Check for consistency with previous definition */
- if (flag_isoc2x)
+ if (flag_isoc2x || flag_tag_compat)
{
tree vistype = previous_tag (enumtype);
if (vistype
@@ -512,7 +512,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
case RECORD_TYPE:
case UNION_TYPE:
- if (flag_isoc2x && !comptypes_same_p (t1, t2))
+ if ((flag_isoc2x || flag_tag_compat) && !comptypes_same_p (t1, t2))
{
gcc_checking_assert (COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2));
gcc_checking_assert (comptypes (t1, t2));
@@ -2911,6 +2911,11 @@ the target (the default). This option is not supported for C++.
@strong{Warning:} the @option{-fsso-struct} switch causes GCC to generate
code that is not binary compatible with code generated without it if the
specified endianness is not the native endianness of the target.
+
+@item -ftag-compat
+@opindex ftag-compat
+This option makes tagged types that are structurally equivalent compatible
+and allows identical redeclarations of tagged types in the same scope.
@end table
@node C++ Dialect Options
@@ -1,5 +1,6 @@
/* PR sanitizer/80460 */
/* { dg-do compile } */
+/* { dg-options "-fno-tag-compat" } */
int
f (int a, struct { int b[a]; } c) /* { dg-warning "anonymous struct declared inside parameter list will not be visible outside of this definition or declaration" } */
@@ -1,7 +1,7 @@
/* Test for handling of tags (6.7.2.3). */
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
/* { dg-do compile } */
-/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors -fno-tag-compat" } */
void
foo (void)
@@ -2,7 +2,7 @@
not match one declared in an outer scope. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
-/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors -fno-tag-compat" } */
struct s;
struct t { struct s *p; } x;
@@ -1,5 +1,6 @@
/* PR c/9928 */
/* { dg-do compile } */
+/* { dg-options "-fno-tag-compat" } */
enum { CODES }; /* { dg-message "note: previous definition" } */
enum { CODES }; /* { dg-error "conflicting types|redeclaration of enumerator" } */
@@ -1,3 +1,5 @@
+/* { dg-options "-fno-tag-compat" } */
+
enum a { A };
enum a { B }; /* { dg-bogus "nested redefinition" } */
/* { dg-error "redeclaration of 'enum a'" "" { target *-*-* } .-1 } */
@@ -3,7 +3,7 @@
diagnosed. Bug 17188. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fno-tag-compat" } */
struct s0 { }; /* { dg-message "note: originally defined here" } */
struct s0;
@@ -1,6 +1,7 @@
/* PR c/18809 */
/* Origin: Andrew Pinski <pinskia@gcc.gnu.org> */
+/* { dg-options "-pedantic-errors -fno-tag-compat" } */
/* { dg-do compile } */
void foo(enum E e) {} /* { dg-error "forward ref" "forward" } */
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-tag-compat" } */
struct color { int i; }; /* { dg-message "note: originally defined here" } */
static const struct color col;
@@ -1,6 +1,6 @@
/* PR c/79983 */
/* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fno-tag-compat" } */
struct S;
struct S { int i; }; /* { dg-message "originally defined here" } */