[clang] 7178ee1 - Revert "[clang] Reject flexible array member in a union in C++"
Mariya Podchishchaeva via cfe-commits
cfe-commits at lists.llvm.org
Wed May 3 06:27:28 PDT 2023
Author: Mariya Podchishchaeva
Date: 2023-05-03T09:25:03-04:00
New Revision: 7178ee190235bd5b6cc7c71d3ccc061d4b12656b
URL: https://github.com/llvm/llvm-project/commit/7178ee190235bd5b6cc7c71d3ccc061d4b12656b
DIFF: https://github.com/llvm/llvm-project/commit/7178ee190235bd5b6cc7c71d3ccc061d4b12656b.diff
LOG: Revert "[clang] Reject flexible array member in a union in C++"
This reverts commit 22e2db6010b029ebd4c6d3d1fd30224d8b3109ef.
Broke buildbots on Windows. It seems standard headers on Windows contain
flexible array members in unions
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticGroups.td
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
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 416d816796514..8d0a9c96a9579 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -55,7 +55,6 @@ C++ Specific Potentially Breaking Changes
-----------------------------------------
- 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 now rejects unions containing a flexible array member.
ABI Changes in This Version
---------------------------
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 4313948515752..0ee43fb8837a1 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -267,6 +267,7 @@ def ExtraSemi : DiagGroup<"extra-semi", [CXX98CompatExtraSemi,
CXX11ExtraSemi]>;
def GNUFlexibleArrayInitializer : DiagGroup<"gnu-flexible-array-initializer">;
+def GNUFlexibleArrayUnionMember : DiagGroup<"gnu-flexible-array-union-member">;
def GNUFoldingConstant : DiagGroup<"gnu-folding-constant">;
def FormatInsufficientArgs : DiagGroup<"format-insufficient-args">;
def FormatExtraArgs : DiagGroup<"format-extra-args">;
@@ -1136,7 +1137,7 @@ def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
GNUConditionalOmittedOperand, GNUDesignator,
GNUEmptyStruct,
VLAExtension, GNUFlexibleArrayInitializer,
- GNUFoldingConstant,
+ GNUFlexibleArrayUnionMember, GNUFoldingConstant,
GNUImaginaryConstant, GNUIncludeNext,
GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
GNUOffsetofExtensions, GNUPointerArith,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c3cb6740a5131..17585752edf8e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6232,9 +6232,6 @@ def ext_variable_sized_type_in_struct : ExtWarn<
def ext_c99_flexible_array_member : Extension<
"flexible array members are a C99 feature">, InGroup<C99>;
-// Flexible array members in unions are not supported, but union case is still
-// present in the diagnostic so it matches TagTypeKind enum and can be emitted
-// with Diag(...) << ... << SomeTagDecl->getTagKind().
def err_flexible_array_virtual_base : Error<
"flexible array member %0 not allowed in "
"%select{struct|interface|union|class|enum}1 which has a virtual base class">;
@@ -6257,10 +6254,15 @@ def ext_flexible_array_empty_aggregate_ms : Extension<
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"
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a5bab074d08e3..4cdf2982b99d5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18690,7 +18690,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
if (Record) {
// Flexible array member.
// Microsoft and g++ is more permissive regarding flexible array.
- // It will accept flexible array as the sole element of a struct/class.
+ // It will accept flexible array in union and also
+ // 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)
@@ -18700,7 +18701,11 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
EnclosingDecl->setInvalidDecl();
continue;
} else if (Record->isUnion())
- DiagID = diag::err_flexible_array_union;
+ DiagID = getLangOpts().MicrosoftExt
+ ? diag::ext_flexible_array_union_ms
+ : getLangOpts().CPlusPlus
+ ? diag::ext_flexible_array_union_gnu
+ : diag::err_flexible_array_union;
else if (NumNamedMembers < 1)
DiagID = getLangOpts().MicrosoftExt
? diag::ext_flexible_array_empty_aggregate_ms
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index c8beae3f52e39..2d5d31f99e500 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -805,7 +805,7 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
// 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->isUnion() && RDecl->hasFlexibleArrayMember())
+ if (RDecl->hasFlexibleArrayMember())
++NumElems;
if (!VerifyOnly && ILE->getNumInits() < NumElems)
ILE->resizeInits(SemaRef.Context, NumElems);
diff --git a/clang/test/Layout/aix-power-alignment-typedef.cpp b/clang/test/Layout/aix-power-alignment-typedef.cpp
index e509a1d4c6abd..908415e72e38d 100644
--- a/clang/test/Layout/aix-power-alignment-typedef.cpp
+++ b/clang/test/Layout/aix-power-alignment-typedef.cpp
@@ -19,3 +19,57 @@ int b = sizeof(A);
} // 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
diff --git a/clang/test/Sema/MicrosoftExtensions.c b/clang/test/Sema/MicrosoftExtensions.c
index 82a441e40023e..50077d9031488 100644
--- a/clang/test/Sema/MicrosoftExtensions.c
+++ b/clang/test/Sema/MicrosoftExtensions.c
@@ -14,8 +14,8 @@ struct PR28407
struct C {
int l;
union {
- 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}} */
+ 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}} */
};
};
diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c
index a487a8dda50eb..7aee651aba225 100644
--- a/clang/test/Sema/init.c
+++ b/clang/test/Sema/init.c
@@ -164,6 +164,3 @@ struct vortexstruct vortexvar = { "asdf" };
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}}
diff --git a/clang/test/SemaCXX/flexible-array-test.cpp b/clang/test/SemaCXX/flexible-array-test.cpp
index c52e0b50471d9..19f130288b610 100644
--- a/clang/test/SemaCXX/flexible-array-test.cpp
+++ b/clang/test/SemaCXX/flexible-array-test.cpp
@@ -16,7 +16,7 @@ void QMap<Key, T>::insert(const Key &, const T &avalue)
struct Rec {
union { // expected-warning-re {{variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}}
- int u0[]; // expected-error {{flexible array member 'u0' in a union is not allowed}}
+ int u0[];
};
int x;
} rec;
@@ -63,7 +63,7 @@ class A {
union B {
int s;
- char c[]; // expected-error {{flexible array member 'c' in a union is not allowed}}
+ char c[];
};
class C {
diff --git a/clang/test/SemaCXX/gnu-flags.cpp b/clang/test/SemaCXX/gnu-flags.cpp
index 6ab619851ff90..3cd18cabe9700 100644
--- a/clang/test/SemaCXX/gnu-flags.cpp
+++ b/clang/test/SemaCXX/gnu-flags.cpp
@@ -8,27 +8,34 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wno-gnu \
// RUN: -Wgnu-anonymous-struct -Wredeclared-class-member \
-// RUN: -Wgnu-folding-constant -Wgnu-empty-struct
+// RUN: -Wgnu-flexible-array-union-member -Wgnu-folding-constant \
+// RUN: -Wgnu-empty-struct
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -DALL -Wno-gnu \
// RUN: -Wgnu-anonymous-struct -Wredeclared-class-member \
-// RUN: -Wgnu-folding-constant -Wgnu-empty-struct
+// RUN: -Wgnu-flexible-array-union-member -Wgnu-folding-constant \
+// RUN: -Wgnu-empty-struct
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -DALL -Wno-gnu \
// RUN: -Wgnu-anonymous-struct -Wredeclared-class-member \
-// RUN: -Wgnu-folding-constant -Wgnu-empty-struct
+// RUN: -Wgnu-flexible-array-union-member -Wgnu-folding-constant \
+// RUN: -Wgnu-empty-struct
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
// RUN: -Wno-gnu-anonymous-struct -Wno-redeclared-class-member \
-// RUN: -Wno-gnu-folding-constant -Wno-gnu-empty-struct
+// RUN: -Wno-gnu-flexible-array-union-member -Wno-gnu-folding-constant \
+// RUN: -Wno-gnu-empty-struct
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -DNONE -Wgnu \
// RUN: -Wno-gnu-anonymous-struct -Wno-redeclared-class-member \
-// RUN: -Wno-gnu-folding-constant -Wno-gnu-empty-struct
+// RUN: -Wno-gnu-flexible-array-union-member -Wno-gnu-folding-constant \
+// RUN: -Wno-gnu-empty-struct
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -DNONE -Wgnu \
// RUN: -Wno-gnu-anonymous-struct -Wno-redeclared-class-member \
-// RUN: -Wno-gnu-folding-constant -Wno-gnu-empty-struct
+// RUN: -Wno-gnu-flexible-array-union-member -Wno-gnu-folding-constant \
+// RUN: -Wno-gnu-empty-struct
// 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
@@ -63,6 +70,19 @@ namespace rcm {
};
}
+
+#if ALL || FLEXIBLEARRAYUNIONMEMBER
+// expected-warning at +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 at +4 {{in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension}}
#endif
diff --git a/clang/test/SemaObjCXX/flexible-array.mm b/clang/test/SemaObjCXX/flexible-array.mm
index 831d6667fabd1..5537876c3039f 100644
--- a/clang/test/SemaObjCXX/flexible-array.mm
+++ b/clang/test/SemaObjCXX/flexible-array.mm
@@ -4,7 +4,7 @@
union VariableSizeUnion {
int s;
- char c[]; //expected-error {{flexible array member 'c' in a union is not allowed}}
+ char c[];
};
@interface LastUnionIvar {
More information about the cfe-commits
mailing list