r316408 - Unnamed bitfields don't block constant evaluation of constexpr ctors

Jordan Rose via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 23 19:17:07 PDT 2017


Author: jrose
Date: Mon Oct 23 19:17:07 2017
New Revision: 316408

URL: http://llvm.org/viewvc/llvm-project?rev=316408&view=rev
Log:
Unnamed bitfields don't block constant evaluation of constexpr ctors

C++14 [dcl.constexpr]p4 states that in the body of a constexpr
constructor,

> every non-variant non-static data member and base class sub-object
  shall be initialized

However, [class.bit]p2 notes that

> Unnamed bit-fields are not members and cannot be initialized.

Therefore, we should make sure to filter them out of the check that
all fields are initialized.

Fixing this makes the constant evaluator a bit smarter, and
specifically allows constexpr constructors to avoid tripping
-Wglobal-constructors when the type contains unnamed bitfields.

Reviewed at https://reviews.llvm.org/D39035.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaCXX/warn-global-constructors.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=316408&r1=316407&r2=316408&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Oct 23 19:17:07 2017
@@ -1818,6 +1818,9 @@ static bool CheckConstantExpression(Eval
       }
     }
     for (const auto *I : RD->fields()) {
+      if (I->isUnnamedBitfield())
+        continue;
+
       if (!CheckConstantExpression(Info, DiagLoc, I->getType(),
                                    Value.getStructField(I->getFieldIndex())))
         return false;

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=316408&r1=316407&r2=316408&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Mon Oct 23 19:17:07 2017
@@ -1931,6 +1931,22 @@ namespace Bitfields {
     };
     static_assert(X::f(3) == -1, "3 should truncate to -1");
   }
+
+  struct HasUnnamedBitfield {
+    unsigned a;
+    unsigned : 20;
+    unsigned b;
+
+    constexpr HasUnnamedBitfield() : a(), b() {}
+    constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
+  };
+
+  void testUnnamedBitfield() {
+    const HasUnnamedBitfield zero{};
+    int a = 1 / zero.b; // expected-warning {{division by zero is undefined}}
+    const HasUnnamedBitfield oneZero{1, 0};
+    int b = 1 / oneZero.b; // expected-warning {{division by zero is undefined}}
+  }
 }
 
 namespace ZeroSizeTypes {

Modified: cfe/trunk/test/SemaCXX/warn-global-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-global-constructors.cpp?rev=316408&r1=316407&r2=316408&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-global-constructors.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-global-constructors.cpp Mon Oct 23 19:17:07 2017
@@ -126,3 +126,22 @@ namespace pr20420 {
 void *array_storage[1];
 const int &global_reference = *(int *)array_storage;
 }
+
+namespace bitfields {
+  struct HasUnnamedBitfield {
+    unsigned a;
+    unsigned : 20;
+    unsigned b;
+
+    constexpr HasUnnamedBitfield() : a(), b() {}
+    constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
+    explicit HasUnnamedBitfield(unsigned a) {}
+  };
+
+  const HasUnnamedBitfield zeroConst{};
+  HasUnnamedBitfield zeroMutable{};
+  const HasUnnamedBitfield explicitConst{1, 2};
+  HasUnnamedBitfield explicitMutable{1, 2};
+  const HasUnnamedBitfield nonConstexprConst{1}; // expected-warning {{global constructor}}
+  HasUnnamedBitfield nonConstexprMutable{1}; // expected-warning {{global constructor}}
+}




More information about the cfe-commits mailing list