Fznamznon updated this revision to Diff 515287.
Fznamznon added a comment.
Reject flexible array members in unions in C++ as well.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D147626/new/
https://reviews.llvm.org/D147626
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaInit.cpp
clang/test/Layout/aix-power-alignment-typedef.cpp
clang/test/Sema/MicrosoftExtensions.c
clang/test/Sema/init.c
clang/test/SemaCXX/flexible-array-test.cpp
clang/test/SemaCXX/gnu-flags.cpp
clang/test/SemaObjCXX/flexible-array.mm
Index: clang/test/SemaObjCXX/flexible-array.mm
===================================================================
--- clang/test/SemaObjCXX/flexible-array.mm
+++ clang/test/SemaObjCXX/flexible-array.mm
@@ -4,7 +4,7 @@
union VariableSizeUnion {
int s;
- char c[];
+ char c[]; //expected-error {{flexible array member 'c' in a union is not allowed}}
};
@interface LastUnionIvar {
Index: clang/test/SemaCXX/gnu-flags.cpp
===================================================================
--- clang/test/SemaCXX/gnu-flags.cpp
+++ clang/test/SemaCXX/gnu-flags.cpp
@@ -35,7 +35,6 @@
// Additional disabled tests:
// %clang_cc1 -fsyntax-only -verify %s -DANONYMOUSSTRUCT -Wno-gnu -Wgnu-anonymous-struct
// %clang_cc1 -fsyntax-only -verify %s -DREDECLAREDCLASSMEMBER -Wno-gnu -Wredeclared-class-member
-// %clang_cc1 -fsyntax-only -verify %s -DFLEXIBLEARRAYUNIONMEMBER -Wno-gnu -Wgnu-flexible-array-union-member
// %clang_cc1 -fsyntax-only -verify %s -DFOLDINGCONSTANT -Wno-gnu -Wgnu-folding-constant
// %clang_cc1 -fsyntax-only -verify %s -DEMPTYSTRUCT -Wno-gnu -Wgnu-empty-struct
@@ -70,19 +69,6 @@
};
}
-
-#if ALL || FLEXIBLEARRAYUNIONMEMBER
-// expected-warning@+6 {{flexible array member 'c1' in a union is a GNU extension}}
-#endif
-
-struct faum {
- int l;
- union {
- int c1[];
- };
-};
-
-
#if (ALL || FOLDINGCONSTANT) && (__cplusplus <= 199711L) // C++03 or earlier modes
// expected-warning@+4 {{in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension}}
#endif
Index: clang/test/SemaCXX/flexible-array-test.cpp
===================================================================
--- clang/test/SemaCXX/flexible-array-test.cpp
+++ clang/test/SemaCXX/flexible-array-test.cpp
@@ -16,7 +16,7 @@
struct Rec {
union { // expected-warning-re {{variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}}
- int u0[];
+ int u0[]; // expected-error {{flexible array member 'u0' in a union is not allowed}}
};
int x;
} rec;
@@ -63,7 +63,7 @@
union B {
int s;
- char c[];
+ char c[]; // expected-error {{flexible array member 'c' in a union is not allowed}}
};
class C {
Index: clang/test/Sema/init.c
===================================================================
--- clang/test/Sema/init.c
+++ clang/test/Sema/init.c
@@ -164,3 +164,6 @@
typedef struct { uintptr_t x : 2; } StructWithBitfield;
StructWithBitfield bitfieldvar = { (uintptr_t)&bitfieldvar }; // expected-error {{initializer element is not a compile-time constant}}
+
+// GH61746
+union { char x[]; } r = {0}; // expected-error {{flexible array member 'x' in a union is not allowed}}
Index: clang/test/Sema/MicrosoftExtensions.c
===================================================================
--- clang/test/Sema/MicrosoftExtensions.c
+++ clang/test/Sema/MicrosoftExtensions.c
@@ -14,8 +14,8 @@
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}} */
+ int c1[]; /* expected-error {{flexible array member 'c1' in a union is not allowed}} */
+ char c2[]; /* expected-error {{flexible array member 'c2' in a union is not allowed}} */
};
};
Index: clang/test/Layout/aix-power-alignment-typedef.cpp
===================================================================
--- clang/test/Layout/aix-power-alignment-typedef.cpp
+++ clang/test/Layout/aix-power-alignment-typedef.cpp
@@ -19,57 +19,3 @@
} // namespace test1
-namespace test2 {
-typedef double Dbl __attribute__((__aligned__(2)));
-typedef Dbl DblArr[];
-
-union U {
- DblArr da;
- char x;
-};
-
-int x = sizeof(U);
-
-// CHECK: 0 | union test2::U
-// CHECK-NEXT: 0 | DblArr da
-// CHECK-NEXT: 0 | char x
-// CHECK-NEXT: | [sizeof=2, dsize=2, align=2, preferredalign=2,
-// CHECK-NEXT: | nvsize=2, nvalign=2, preferrednvalign=2]
-
-} // namespace test2
-
-namespace test3 {
-typedef double DblArr[] __attribute__((__aligned__(2)));
-
-union U {
- DblArr da;
- char x;
-};
-
-int x = sizeof(U);
-
-// CHECK: 0 | union test3::U
-// CHECK-NEXT: 0 | DblArr da
-// CHECK-NEXT: 0 | char x
-// CHECK-NEXT: | [sizeof=2, dsize=2, align=2, preferredalign=2,
-// CHECK-NEXT: | nvsize=2, nvalign=2, preferrednvalign=2]
-
-} // namespace test3
-
-namespace test4 {
-typedef double Dbl __attribute__((__aligned__(2)));
-
-union U {
- Dbl DblArr[];
- char x;
-};
-
-int x = sizeof(U);
-
-// CHECK: 0 | union test4::U
-// CHECK-NEXT: 0 | Dbl[] DblArr
-// CHECK-NEXT: 0 | char x
-// CHECK-NEXT: | [sizeof=2, dsize=2, align=2, preferredalign=2,
-// CHECK-NEXT: | nvsize=2, nvalign=2, preferrednvalign=2]
-
-} // namespace test4
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -805,7 +805,7 @@
// order to leave them uninitialized, the ILE is expanded and the extra
// fields are then filled with NoInitExpr.
unsigned NumElems = numStructUnionElements(ILE->getType());
- if (RDecl->hasFlexibleArrayMember())
+ if (!RDecl->isUnion() && RDecl->hasFlexibleArrayMember())
++NumElems;
if (!VerifyOnly && ILE->getNumInits() < NumElems)
ILE->resizeInits(SemaRef.Context, NumElems);
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -18684,8 +18684,7 @@
if (Record) {
// Flexible array member.
// Microsoft and g++ is more permissive regarding flexible array.
- // It will accept flexible array in union and also
- // as the sole element of a struct/class.
+ // It will accept flexible array as the sole element of a struct/class.
unsigned DiagID = 0;
if (!Record->isUnion() && !IsLastField) {
Diag(FD->getLocation(), diag::err_flexible_array_not_at_end)
@@ -18695,11 +18694,7 @@
EnclosingDecl->setInvalidDecl();
continue;
} else if (Record->isUnion())
- DiagID = getLangOpts().MicrosoftExt
- ? diag::ext_flexible_array_union_ms
- : getLangOpts().CPlusPlus
- ? diag::ext_flexible_array_union_gnu
- : diag::err_flexible_array_union;
+ DiagID = diag::err_flexible_array_union;
else if (NumNamedMembers < 1)
DiagID = getLangOpts().MicrosoftExt
? diag::ext_flexible_array_empty_aggregate_ms
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6244,15 +6244,10 @@
InGroup<MicrosoftFlexibleArray>;
def err_flexible_array_union : Error<
"flexible array member %0 in a union is not allowed">;
-def ext_flexible_array_union_ms : Extension<
- "flexible array member %0 in a union is a Microsoft extension">,
- InGroup<MicrosoftFlexibleArray>;
def ext_flexible_array_empty_aggregate_gnu : Extension<
"flexible array member %0 in otherwise empty "
"%select{struct|interface|union|class|enum}1 is a GNU extension">,
InGroup<GNUEmptyStruct>;
-def ext_flexible_array_union_gnu : Extension<
- "flexible array member %0 in a union is a GNU extension">, InGroup<GNUFlexibleArrayUnionMember>;
def err_flexible_array_not_at_end : Error<
"flexible array member %0 with type %1 is not at the end of"
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -55,6 +55,7 @@
-----------------------------------------
- Clang won't search for coroutine_traits in std::experimental namespace any more.
Clang will only search for std::coroutine_traits for coroutines then.
+- Clang doesn't accept flexible array members in unions in C++ anymore.
ABI Changes in This Version
---------------------------
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits