mstorsjo created this revision.
mstorsjo added reviewers: rsmith, rjmccall, rnk, Mordante.
Herald added a project: clang.

GCC 7 and earlier, when targeting MinGW, seems to have a bug in layout/size of 
bitfield structs if they contain a nested enum, making the size of the struct 8 
bytes, while we have a static assert requiring it to be 4 bytes or less.

While this clearly is a GCC bug, the workaround (moving the enum out of the 
bitfield) also is very nonintrusive and matches other existing enums there.

Testcase:

  $ cat bitfield.cpp
  struct MyStruct {
    unsigned a : 1;
    enum { SomeValue = 42 };
    unsigned b : 1;
  };      
  int StructSize = sizeof(struct MyStruct);
  $ x86_64-w64-mingw32-g++ -S -o - bitfield.cpp | grep -C 2 StructSize 
          .file   "bitfield.cpp"
          .text
          .globl  StructSize
          .data
          .align 4
  StructSize:
          .long   8 
          .ident  "GCC: (GNU) 7.3-win32 20180312"


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71650

Files:
  clang/include/clang/AST/Decl.h


Index: clang/include/clang/AST/Decl.h
===================================================================
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -900,6 +900,8 @@
     DAK_Normal
   };
 
+  enum { NumScopeDepthOrObjCQualsBits = 7 };
+
   class ParmVarDeclBitfields {
     friend class ASTDeclReader;
     friend class ParmVarDecl;
@@ -922,8 +924,6 @@
     /// Whether this parameter is an ObjC method parameter or not.
     unsigned IsObjCMethodParam : 1;
 
-    enum { NumScopeDepthOrObjCQualsBits = 7 };
-
     /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
     /// Otherwise, the number of function parameter scopes enclosing
     /// the function parameter scope in which this parameter was
@@ -1654,7 +1654,7 @@
   }
 
   static constexpr unsigned getMaxFunctionScopeDepth() {
-    return (1u << ParmVarDeclBitfields::NumScopeDepthOrObjCQualsBits) - 1;
+    return (1u << NumScopeDepthOrObjCQualsBits) - 1;
   }
 
   /// Returns the index of this parameter in its prototype or method scope.


Index: clang/include/clang/AST/Decl.h
===================================================================
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -900,6 +900,8 @@
     DAK_Normal
   };
 
+  enum { NumScopeDepthOrObjCQualsBits = 7 };
+
   class ParmVarDeclBitfields {
     friend class ASTDeclReader;
     friend class ParmVarDecl;
@@ -922,8 +924,6 @@
     /// Whether this parameter is an ObjC method parameter or not.
     unsigned IsObjCMethodParam : 1;
 
-    enum { NumScopeDepthOrObjCQualsBits = 7 };
-
     /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
     /// Otherwise, the number of function parameter scopes enclosing
     /// the function parameter scope in which this parameter was
@@ -1654,7 +1654,7 @@
   }
 
   static constexpr unsigned getMaxFunctionScopeDepth() {
-    return (1u << ParmVarDeclBitfields::NumScopeDepthOrObjCQualsBits) - 1;
+    return (1u << NumScopeDepthOrObjCQualsBits) - 1;
   }
 
   /// Returns the index of this parameter in its prototype or method scope.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to