diff --git a/libtcc.c b/libtcc.c index 533c14da..d33cdb03 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1463,6 +1463,7 @@ static const FlagDef flag_defs[] = { { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" }, { offsetof(TCCState, nocommon), FD_INVERT, "common" }, { offsetof(TCCState, leading_underscore), 0, "leading-underscore" }, + { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, }; /* set/reset a flag */ diff --git a/tcc-doc.texi b/tcc-doc.texi index bcd19e13..909af720 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -236,6 +236,11 @@ Do not generate common symbols for uninitialized data. @item -fleading-underscore Add a leading underscore at the beginning of each C symbol. +@item -fms-extensions +Allow a MS C compiler extensions to the language. Curretly this +assume a nested named structure declaration without identifier behave +like an unnamed one. + @end table Warning options: diff --git a/tcc.h b/tcc.h index 96c0333e..402e9cad 100644 --- a/tcc.h +++ b/tcc.h @@ -602,6 +602,7 @@ struct TCCState { /* C language options */ int char_is_unsigned; int leading_underscore; + int ms_extensions; /* allow nested named struct w/o identifier behave like unnamed */ /* warning switches */ int warn_write_strings; diff --git a/tccgen.c b/tccgen.c index 00a80863..3b87d0a4 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2959,8 +2959,17 @@ static void struct_decl(CType *type, int u, int tdef) type1 = btype; if (tok != ':') { type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); - if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) - expect("identifier"); + if (v == 0) { + if ((type1.t & VT_BTYPE) != VT_STRUCT) + expect("identifier"); + else { + int v = btype.ref->v; + if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { + if (tcc_state->ms_extensions == 0) + expect("identifier"); + } + } + } if (type_size(&type1, &align) < 0) { if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) flexible = 1; @@ -6121,7 +6130,11 @@ static int decl0(int l, int is_for_loop_init) if (((btype.t & VT_BTYPE) == VT_ENUM || (btype.t & VT_BTYPE) == VT_STRUCT) && tok == ';') { - /* we accept no variable after */ + if ((btype.t & VT_BTYPE) == VT_STRUCT) { + int v = btype.ref->v; + if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) + tcc_warning("unnamed struct/union that defines no instances"); + } next(); continue; }