[PATCH] D28427: Allow constexpr construction of subobjects unconditionally, not just in C++14.
David L. Jones via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 9 10:23:08 PST 2017
dlj updated this revision to Diff 83647.
dlj added a comment.
- Add a test, and fix codegen test (the array init is now constant, even though there is a dtor).
https://reviews.llvm.org/D28427
Files:
lib/AST/ExprConstant.cpp
test/CXX/basic/basic.start/basic.start.init/p2.cpp
test/CodeGenCXX/global-array-destruction.cpp
Index: test/CodeGenCXX/global-array-destruction.cpp
===================================================================
--- test/CodeGenCXX/global-array-destruction.cpp
+++ test/CodeGenCXX/global-array-destruction.cpp
@@ -39,15 +39,17 @@
T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
// CHECK: call {{.*}} @__cxa_atexit
-// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @t to %struct.T*), i64 6
+// CHECK: getelementptr inbounds {{.*}}
+// CHECK: bitcast {{.*}} to %struct.T*
// CHECK: call void @_ZN1TD1Ev
// CHECK: icmp eq {{.*}} @t
// CHECK: br i1 {{.*}}
static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
// CHECK: call {{.*}} @__cxa_atexit
-// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @_ZL2t2 to %struct.T*), i64 6
+// CHECK: getelementptr inbounds {{.*}}
+// CHECK: bitcast {{.*}} to %struct.T*
// CHECK: call void @_ZN1TD1Ev
// CHECK: icmp eq {{.*}} @_ZL2t
// CHECK: br i1 {{.*}}
Index: test/CXX/basic/basic.start/basic.start.init/p2.cpp
===================================================================
--- /dev/null
+++ test/CXX/basic/basic.start/basic.start.init/p2.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++11
+// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++14
+// expected-no-diagnostics
+
+struct foo_t {
+ union {
+ int i;
+ volatile int j;
+ } u;
+};
+
+__attribute__((__require_constant_initialization__))
+static const foo_t x = {{0}};
+
+union foo_u {
+ int i;
+ volatile int j;
+};
+
+__attribute__((__require_constant_initialization__))
+static const foo_u y = {0};
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -1627,8 +1627,17 @@
// C++1y: A constant initializer for an object o [...] may also invoke
// constexpr constructors for o and its subobjects even if those objects
// are of non-literal class types.
- if (Info.getLangOpts().CPlusPlus14 && This &&
- Info.EvaluatingDecl == This->getLValueBase())
+ //
+ // C++11 missed this detail for aggregates, so classes like this:
+ // struct foo_t { union { int i; volatile int j; } u; };
+ // are not (obviously) initializable like so:
+ // __attribute__((__require_constant_initialization__))
+ // static const foo_t x = {{0}};
+ // because "i" is a subobject with non-literal initialization (due to the
+ // volatile member of the union). See:
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677
+ // Therefore, we use the C++1y behavior.
+ if (This && Info.EvaluatingDecl == This->getLValueBase())
return true;
// Prvalue constant expressions must be of literal types.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28427.83647.patch
Type: text/x-patch
Size: 2757 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170109/258b0a6c/attachment-0001.bin>
More information about the cfe-commits
mailing list