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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to