From: Francois Pichet Date: Wed, 15 Sep 2010 00:14:08 +0000 (+0000) Subject: Microsoft's flexible array rules relaxation: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09246183715f4b0a8728a3827bfe894b6c6016b9;p=clang Microsoft's flexible array rules relaxation: - in union - as the only element of a struct/class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113909 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 9edceb820c..9aadc1efa1 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1965,6 +1965,13 @@ def ext_flexible_array_in_array : Extension< "%0 may not be used as an array element due to flexible array member">; def err_flexible_array_init_nonempty : Error< "non-empty initialization of flexible array member inside subobject">; +def ext_flexible_array_empty_aggregate : Extension< + "flexible array member %0 in otherwise empty %select{struct|class}1 " + "is a Microsoft extension">, InGroup; +def ext_flexible_array_union : Extension< + "flexible array member %0 in a union is a Microsoft extension">, + InGroup; + def err_flexible_array_init_needs_braces : Error< "flexible array requires brace-enclosed initializer">; def err_illegal_decl_array_of_functions : Error< @@ -2869,8 +2876,8 @@ def err_anonymous_struct_member_redecl : Error< def err_anonymous_record_with_type : Error< "types cannot be declared in an anonymous %select{struct|union}0">; def ext_anonymous_record_with_type : Extension< - "types declared in an anonymous %select{struct|union}0 are a Microsoft extension">, - InGroup; + "types declared in an anonymous %select{struct|union}0 are a Microsoft " + "extension">, InGroup; def err_anonymous_record_with_function : Error< "functions cannot be declared in an anonymous %select{struct|union}0">; def err_anonymous_record_with_static : Error< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 21b328d64c..e314c1acfe 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6619,10 +6619,22 @@ void Sema::ActOnFields(Scope* S, FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); continue; - } else if (FDTy->isIncompleteArrayType() && i == NumFields - 1 && - Record && !Record->isUnion()) { + } else if (FDTy->isIncompleteArrayType() && Record && + ((i == NumFields - 1 && !Record->isUnion()) || + (getLangOptions().Microsoft && + (i == NumFields - 1 || Record->isUnion())))) { // Flexible array member. - if (NumNamedMembers < 1) { + // Microsoft is more permissive regarding flexible array. + // It will accept flexible array in union and also + // as the sole element of a struct/class. + if (getLangOptions().Microsoft) { + if (Record->isUnion()) + Diag(FD->getLocation(), diag::ext_flexible_array_union) + << FD->getDeclName(); + else if (NumFields == 1) + Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate) + << FD->getDeclName() << Record->getTagKind(); + } else if (NumNamedMembers < 1) { Diag(FD->getLocation(), diag::err_flexible_array_empty_struct) << FD->getDeclName(); FD->setInvalidDecl(); @@ -6637,7 +6649,6 @@ void Sema::ActOnFields(Scope* S, EnclosingDecl->setInvalidDecl(); continue; } - // Okay, we have a legal flexible array member at the end of the struct. if (Record) Record->setHasFlexibleArrayMember(true); diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c new file mode 100644 index 0000000000..5a434aab26 --- /dev/null +++ b/test/Sema/MicrosoftExtensions.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions + + +struct A +{ + int a[]; /* expected-warning {{flexible array member 'a' in otherwise empty struct is a Microsoft extension}} */ +}; + +struct C { + int l; + union { + int c1[]; /* expected-warning {{flexible array member 'c1' in a union is a Microsoft extension}} */ + char c2[]; /* expected-warning {{flexible array member 'c2' in a union is a Microsoft extension}} */ + }; +}; + + +struct D { + int l; + int D[]; +};