aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois Pichet <pichet2000@gmail.com>2010-09-15 00:14:08 +0000
committerFrancois Pichet <pichet2000@gmail.com>2010-09-15 00:14:08 +0000
commit09246183715f4b0a8728a3827bfe894b6c6016b9 (patch)
tree67bee8e4bb65f12891573d7629180003303141d9
parent0268810a46780144a2d5fb5a017c938d1199189c (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td11
-rw-r--r--lib/Sema/SemaDecl.cpp19
-rw-r--r--test/Sema/MicrosoftExtensions.c21
3 files changed, 45 insertions, 6 deletions
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<Microsoft>;
+def ext_flexible_array_union : Extension<
+ "flexible array member %0 in a union is a Microsoft extension">,
+ InGroup<Microsoft>;
+
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<Microsoft>;
+ "types declared in an anonymous %select{struct|union}0 are a Microsoft "
+ "extension">, InGroup<Microsoft>;
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[];
+};