Commit 750491fc by Richard Henderson Committed by Richard Henderson

c-common.c (flag_ms_extensions): Move from c++ front end.

        * c-common.c (flag_ms_extensions): Move from c++ front end.
        * c-common.h (flag_ms_extensions): Declare.
        * c-decl.c (c_decode_option): Add -fms-extensions.
        (grokfield): Don't accept anonymous structures in ISO C mode;
        accept only unnamed anonymous structures in GNU C mode; accept
        Plan 9 extensions in MS mode.
        * c-parse.in (SAVE_EXT_FLAGS, RESTORE_EXT_FLAGS): Rename from
        SAVE/RESTORE_WARN_FLAGS; add flag_iso frobbing; update all callers.
        (extension): Clear flag_iso.
        * doc/invoke.texi (C Dialect Options): Add -fms-extensions.

        * cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common.

        * g++.dg/ext/anon-struct1.C: New.
        * g++.dg/ext/anon-struct2.C: New.
        * g++.dg/ext/anon-struct3.C: New.
        * gcc.dg/anon-struct-1.c: New.
        * gcc.dg/anon-struct-2.c: New.
        * gcc.dg/anon-struct-3.c: New.
        * gcc.dg/20011008-1.c: Adjust warning text.
        * gcc.dg/20020527-1.c: Add -fms-extensions.

From-SVN: r54670
parent 0931db71
2002-06-16 Richard Henderson <rth@redhat.com>
* c-common.c (flag_ms_extensions): Move from c++ front end.
* c-common.h (flag_ms_extensions): Declare.
* c-decl.c (c_decode_option): Add -fms-extensions.
(grokfield): Don't accept anonymous structures in ISO C mode;
accept only unnamed anonymous structures in GNU C mode; accept
Plan 9 extensions in MS mode.
* c-parse.in (SAVE_EXT_FLAGS, RESTORE_EXT_FLAGS): Rename from
SAVE/RESTORE_WARN_FLAGS; add flag_iso frobbing; update all callers.
(extension): Clear flag_iso.
* doc/invoke.texi (C Dialect Options): Add -fms-extensions.
2002-06-16 Hans-Peter Nilsson <hp@axis.com>
PR target/7042
......
......@@ -220,6 +220,9 @@ int flag_short_double;
int flag_short_wchar;
/* Nonzero means allow Microsoft extensions without warnings or errors. */
int flag_ms_extensions;
/* Nonzero means warn about use of multicharacter literals. */
int warn_multichar = 1;
......
......@@ -396,6 +396,9 @@ extern int flag_short_double;
extern int flag_short_wchar;
/* Nonzero means allow Microsoft extensions without warnings or errors. */
extern int flag_ms_extensions;
/* Nonzero means warn about use of multicharacter literals. */
extern int warn_multichar;
......
......@@ -629,6 +629,10 @@ c_decode_option (argc, argv)
flag_no_asm = 0;
else if (!strcmp (p, "-fno-asm"))
flag_no_asm = 1;
else if (!strcmp (p, "-fms-extensions"))
flag_ms_extensions = 1;
else if (!strcmp (p, "-fno-ms-extensions"))
flag_ms_extensions = 0;
else if (!strcmp (p, "-fbuiltin"))
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
......@@ -5359,15 +5363,44 @@ grokfield (filename, line, declarator, declspecs, width)
if (declarator == NULL_TREE && width == NULL_TREE)
{
/* This is an unnamed decl. We only support unnamed
structs/unions, so check for other things and refuse them. */
/* This is an unnamed decl.
If we have something of the form "union { list } ;" then this
is the anonymous union extension. Similarly for struct.
If this is something of the form "struct foo;", then
If MS extensions are enabled, this is handled as an
anonymous struct.
Otherwise this is a forward declaration of a structure tag.
If this is something of the form "foo;" and foo is a TYPE_DECL, then
If MS extensions are enabled and foo names a structure, then
again this is an anonymous struct.
Otherwise this is an error.
Oh what a horrid tangled web we weave. I wonder if MS consiously
took this from Plan 9 or if it was an accident of implementation
that took root before someone noticed the bug... */
tree type = TREE_VALUE (declspecs);
if (TREE_CODE (type) == TYPE_DECL)
if (flag_ms_extensions && TREE_CODE (type) == TYPE_DECL)
type = TREE_TYPE (type);
if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE)
if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)
{
if (flag_ms_extensions)
; /* ok */
else if (flag_iso)
goto warn_unnamed_field;
else if (TYPE_NAME (type) == NULL)
; /* ok */
else
goto warn_unnamed_field;
}
else
{
error ("unnamed fields of type other than struct or union are not allowed");
warn_unnamed_field:
warning ("declaration does not declare anything");
return NULL_TREE;
}
}
......
......@@ -298,17 +298,19 @@ static GTY(()) tree declspec_stack;
/* For __extension__, save/restore the warning flags which are
controlled by __extension__. */
#define SAVE_WARN_FLAGS() \
#define SAVE_EXT_FLAGS() \
size_int (pedantic \
| (warn_pointer_arith << 1) \
| (warn_traditional << 2))
| (warn_traditional << 2) \
| (flag_iso << 3))
#define RESTORE_WARN_FLAGS(tval) \
#define RESTORE_EXT_FLAGS(tval) \
do { \
int val = tree_low_cst (tval, 0); \
pedantic = val & 1; \
warn_pointer_arith = (val >> 1) & 1; \
warn_traditional = (val >> 2) & 1; \
flag_iso = (val >> 3) & 1; \
} while (0)
ifobjc
......@@ -394,7 +396,7 @@ end ifobjc
else
error ("argument of `asm' is not a constant string"); }
| extension extdef
{ RESTORE_WARN_FLAGS ($1); }
{ RESTORE_EXT_FLAGS ($1); }
;
datadef:
......@@ -517,7 +519,7 @@ unary_expr:
/* __extension__ turns off -pedantic for following primary. */
| extension cast_expr %prec UNARY
{ $$ = $2;
RESTORE_WARN_FLAGS ($1); }
RESTORE_EXT_FLAGS ($1); }
| unop cast_expr %prec UNARY
{ $$ = build_unary_op ($1, $2, 0);
overflow_warning ($$); }
......@@ -865,7 +867,7 @@ decl:
| declspecs ';'
{ shadow_tag ($1); }
| extension decl
{ RESTORE_WARN_FLAGS ($1); }
{ RESTORE_EXT_FLAGS ($1); }
;
/* A list of declaration specifiers. These are:
......@@ -1863,7 +1865,7 @@ component_decl:
{ $$ = NULL_TREE; }
| extension component_decl
{ $$ = $2;
RESTORE_WARN_FLAGS ($1); }
RESTORE_EXT_FLAGS ($1); }
;
components:
......@@ -2664,10 +2666,11 @@ identifiers_or_typenames:
extension:
EXTENSION
{ $$ = SAVE_WARN_FLAGS();
{ $$ = SAVE_EXT_FLAGS();
pedantic = 0;
warn_pointer_arith = 0;
warn_traditional = 0; }
warn_traditional = 0;
flag_iso = 0; }
;
ifobjc
......
2002-06-16 Richard Henderson <rth@redhat.com>
* cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common.
2002-06-15 Gabriel Dos Reis <gdr@codesourcery.com>
* cp-tree.h (compiler_error): Remove declaration.
......
......@@ -3200,9 +3200,6 @@ typedef enum base_kind {
binfo. */
} base_kind;
/* Nonzero means allow Microsoft extensions without a pedwarn. */
extern int flag_ms_extensions;
/* Non-zero means warn in function declared in derived class has the
same name as a virtual in the base class, but fails to match the
type signature of any virtual function in the base class. */
......
......@@ -299,10 +299,6 @@ int warn_deprecated = 1;
#endif
int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
/* Nonzero means allow Microsoft extensions without a pedwarn. */
int flag_ms_extensions;
/* C++ specific flags. */
/* Nonzero means we should attempt to elide constructors when possible. */
......
......@@ -164,7 +164,7 @@ in the following sections.
@gccoptlist{
-ansi -std=@var{standard} -aux-info @var{filename} @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} @gol
-fhosted -ffreestanding @gol
-fhosted -ffreestanding -fms-extensions @gol
-trigraphs -traditional -traditional-cpp @gol
-fallow-single-precision -fcond-mismatch @gol
-fsigned-bitfields -fsigned-char @gol
......@@ -1141,6 +1141,10 @@ This is equivalent to @option{-fno-hosted}.
@xref{Standards,,Language Standards Supported by GCC}, for details of
freestanding and hosted environments.
@item -fms-extensions
@opindex fms-extensions
Accept some non-standard constructs used in Microsoft header files.
@item -trigraphs
@opindex trigraphs
Support ISO C trigraphs. The @option{-ansi} option (and @option{-std}
......
2002-06-16 Richard Henderson <rth@redhat.com>
* g++.dg/ext/anon-struct1.C: New.
* g++.dg/ext/anon-struct2.C: New.
* g++.dg/ext/anon-struct3.C: New.
* gcc.dg/anon-struct-1.c: New.
* gcc.dg/anon-struct-2.c: New.
* gcc.dg/anon-struct-3.c: New.
* gcc.dg/20011008-1.c: Adjust warning text.
* gcc.dg/20020527-1.c: Add -fms-extensions.
2002-06-16 Richard Henderson <rth@redhat.com>
* gcc.dg/20020531-1.c: Add LL specifier to avoid warning.
2002-06-15 Hans-Peter Nilsson <hp@axis.com>
......
/* { dg-options "-ansi -pedantic -pedantic-errors" } */
/* In strict ISO C++ mode, we don't recognize the anonymous struct
extension or any Microsoft C extensions. */
struct A { char a; };
struct B {
struct A; /* forward decl of B::A. */
char b;
};
char testB[sizeof(B) == sizeof(A) ? 1 : -1];
struct C {
struct D { char d; }; /* decl of C::D. */
char c;
};
char testC[sizeof(C) == sizeof(A) ? 1 : -1];
char testD[sizeof(C::D) == sizeof(A) ? 1 : -1];
/* GNU extension. */
struct E {
struct { char z; }; /* { dg-error "prohibits anonymous structs" } */
char e;
};
typedef struct A typedef_A;
struct F {
typedef_A; /* { dg-error "does not declare anything" } */
char f;
};
char testF[sizeof(struct F) == sizeof(struct A) ? 1 : -1];
/* __extension__ enables GNU C mode for the duration of the declaration. */
__extension__ struct G {
struct { char z; };
char g;
};
char testG[sizeof(G) == 2 * sizeof(A) ? 1 : -1];
struct H {
__extension__ struct { char z; };
char h;
};
char testH[sizeof(H) == 2 * sizeof(A) ? 1 : -1];
/* Make sure __extension__ gets turned back off. */
struct I {
struct { char z; }; /* { dg-error "prohibits anonymous structs" } */
char i;
};
/* { dg-options "" } */
/* In GNU C++ mode, we recognize the anonymous struct extension,
but not Microsoft C extensions. */
struct A { char a; };
struct B {
struct A; /* forward decl of B::A. */
char b;
};
char testB[sizeof(B) == sizeof(A) ? 1 : -1];
struct C {
struct D { char d; }; /* decl of C::D. */
char c;
};
char testC[sizeof(C) == sizeof(A) ? 1 : -1];
char testD[sizeof(C::D) == sizeof(A) ? 1 : -1];
/* GNU extension. */
struct E {
struct { char z; };
char e;
};
char testE[sizeof(E) == 2 * sizeof(A) ? 1 : -1];
char testEz[sizeof( ((E *)0)->z )];
typedef struct A typedef_A;
struct F {
typedef_A; /* { dg-error "does not declare anything" } */
char f;
};
char testF[sizeof(F) == sizeof(A) ? 1 : -1];
/* Test that __extension__ does the right thing coming _from_ GNU C mode. */
__extension__ struct G {
struct { char z; };
char g;
};
char testG[sizeof(G) == 2 * sizeof(A) ? 1 : -1];
struct H {
struct { char z; };
char h;
};
char testH[sizeof(H) == 2 * sizeof(A) ? 1 : -1];
/* { dg-options "-fms-extensions" } */
/* Verify that enabling Microsoft mode doesn't twist C++ as much as
their corresponding C extensions. Checked vs
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
*/
struct A { char a; };
struct B {
struct A; /* forward decl of B::A. */
char b;
};
char testB[sizeof(B) == sizeof(A) ? 1 : -1];
struct C {
struct D { char d; }; /* decl of C::D. */
char c;
};
char testC[sizeof(C) == sizeof(A) ? 1 : -1];
char testD[sizeof(C::D) == sizeof(A) ? 1 : -1];
struct E {
struct { char z; };
char e;
};
char testE[sizeof(E) == 2 * sizeof(A) ? 1 : -1];
char testEz[sizeof( ((E *)0)->z )];
typedef struct A typedef_A;
struct F {
typedef_A; /* { dg-error "does not declare anything" } */
char f;
};
char testF[sizeof(F) == sizeof(A) ? 1 : -1];
/* { dg-do compile } */
/* { dg-options "-O0" } */
struct { int; int q; } a; /* { dg-error "unnamed" } */
struct { int; int q; } a; /* { dg-warning "does not declare anything" } */
struct { union {int x;}; int q; } b;
struct { struct {int x;}; int q; } c;
union { union {int x;}; int q; } d;
......
......@@ -2,7 +2,7 @@
Test whether an unnamed field with user defined type - struct or union is
accepted. */
/* { dg-do compile } */
/* { dg-options "" } */
/* { dg-options "-fms-extensions" } */
typedef struct {
unsigned short a;
......
/* { dg-options "-std=iso9899:1990" } */
/* In strict ISO C mode, we don't recognize the anonymous struct/union
extension or any Microsoft extensions. */
struct A { char a; };
/* MS extension. */
struct B {
struct A; /* { dg-warning "does not declare anything" } */
char b;
};
char testB[sizeof(struct B) == sizeof(struct A) ? 1 : -1];
/* MS extension. */
struct C {
struct D { char d; }; /* { dg-warning "does not declare anything" } */
char c;
};
char testC[sizeof(struct C) == sizeof(struct A) ? 1 : -1];
char testD[sizeof(struct D) == sizeof(struct A) ? 1 : -1];
/* GNU extension. */
struct E {
struct { char z; }; /* { dg-warning "does not declare anything" } */
char e;
};
char testE[sizeof(struct E) == sizeof(struct A) ? 1 : -1];
/* MS extension. */
typedef struct A typedef_A;
struct F {
typedef_A; /* { dg-warning "does not declare anything" } */
char f;
};
char testF[sizeof(struct F) == sizeof(struct A) ? 1 : -1];
/* __extension__ enables GNU C mode for the duration of the declaration. */
__extension__ struct G {
struct { char z; };
char g;
};
char testG[sizeof(struct G) == 2 * sizeof(struct A) ? 1 : -1];
struct H {
__extension__ struct { char z; };
char h;
};
char testH[sizeof(struct H) == 2 * sizeof(struct A) ? 1 : -1];
/* Make sure __extension__ gets turned back off. */
struct I {
struct { char z; }; /* { dg-warning "does not declare anything" } */
char i;
};
char testI[sizeof(struct I) == sizeof(struct A) ? 1 : -1];
/* { dg-options "-std=gnu89" } */
/* In GNU C mode, we recognize the anonymous struct/union extension,
but not Microsoft extensions. */
struct A { char a; };
/* MS extension. */
struct B {
struct A; /* { dg-warning "does not declare anything" } */
char b;
};
char testB[sizeof(struct B) == sizeof(struct A) ? 1 : -1];
/* MS extension. */
struct C {
struct D { char d; }; /* { dg-warning "does not declare anything" } */
char c;
};
char testC[sizeof(struct C) == sizeof(struct A) ? 1 : -1];
char testD[sizeof(struct D) == sizeof(struct A) ? 1 : -1];
/* GNU extension. */
struct E {
struct { char z; };
char e;
};
char testE[sizeof(struct E) == 2 * sizeof(struct A) ? 1 : -1];
/* MS extension. */
typedef struct A typedef_A;
struct F {
typedef_A; /* { dg-warning "does not declare anything" } */
char f;
};
char testF[sizeof(struct F) == sizeof(struct A) ? 1 : -1];
/* Test that __extension__ does the right thing coming _from_ GNU C mode. */
__extension__ struct G {
struct { char z; };
char g;
};
char testG[sizeof(struct G) == 2 * sizeof(struct A) ? 1 : -1];
struct H {
struct { char z; };
char h;
};
char testH[sizeof(struct H) == 2 * sizeof(struct A) ? 1 : -1];
/* { dg-options "-std=gnu89 -fms-extensions" } */
/* Enabling Microsoft mode makes all of the tests equivalent. Checked vs
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
*/
struct A { char a; };
struct B {
struct A;
char b;
};
char testB[sizeof(struct B) == 2 * sizeof(struct A) ? 1 : -1];
struct C {
struct D { char d; };
char c;
};
char testC[sizeof(struct C) == 2 * sizeof(struct A) ? 1 : -1];
char testD[sizeof(struct D) == sizeof(struct A) ? 1 : -1];
struct E {
struct { char z; };
char e;
};
char testE[sizeof(struct E) == 2 * sizeof(struct A) ? 1 : -1];
typedef struct A typedef_A;
struct F {
typedef_A;
char f;
};
char testF[sizeof(struct F) == 2 * sizeof(struct A) ? 1 : -1];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment