nickdesaulniers updated this revision to Diff 543009.
nickdesaulniers edited the summary of this revision.
nickdesaulniers added a comment.
- add link to issue tracker
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76096/new/
https://reviews.llvm.org/D76096
Files:
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp
clang/test/CodeGen/builtin-constant-p.c
clang/test/CodeGen/const-init.c
clang/test/Sema/builtins.c
clang/test/Sema/init.c
Index: clang/test/Sema/init.c
===================================================================
--- clang/test/Sema/init.c
+++ clang/test/Sema/init.c
@@ -164,3 +164,36 @@
typedef struct { uintptr_t x : 2; } StructWithBitfield;
StructWithBitfield bitfieldvar = { (uintptr_t)&bitfieldvar }; // expected-error {{initializer element is not a compile-time constant}}
+
+// PR45157
+struct PR4517_foo {};
+struct PR4517_bar {
+ struct PR4517_foo foo;
+};
+const struct PR4517_foo my_foo = {};
+struct PR4517_bar my_bar = {
+ .foo = my_foo, // no-warning
+};
+struct PR4517_bar my_bar2 = (struct PR4517_bar){
+ .foo = my_foo, // no-warning
+};
+struct PR4517_bar my_bar3 = {
+ my_foo, // no-warning
+};
+struct PR4517_bar my_bar4 = (struct PR4517_bar){
+ my_foo // no-warning
+};
+extern const struct PR4517_foo my_foo2;
+struct PR4517_bar my_bar5 = {
+ .foo = my_foo2, // expected-error {{initializer element is not a compile-time constant}}
+};
+int PR4517_a[2] = {0, 1};
+const int PR4517_ca[2] = {0, 1};
+int PR4517_idx = 0;
+const int PR4517_idxc = 1;
+int PR4517_x1 = PR4517_a[PR4517_idx]; // expected-error {{initializer element is not a compile-time constant}}
+int PR4517_x2 = PR4517_a[PR4517_idxc]; // expected-error {{initializer element is not a compile-time constant}}
+int PR4517_x3 = PR4517_a[0]; // expected-error {{initializer element is not a compile-time constant}}
+int PR4517_y1 = PR4517_ca[PR4517_idx]; // expected-error {{initializer element is not a compile-time constant}}
+int PR4517_y2 = PR4517_ca[PR4517_idxc]; // no-warning
+int PR4517_y3 = PR4517_ca[0]; // no-warning
Index: clang/test/Sema/builtins.c
===================================================================
--- clang/test/Sema/builtins.c
+++ clang/test/Sema/builtins.c
@@ -131,7 +131,7 @@
const int test17_n = 0;
const char test17_c[] = {1, 2, 3, 0};
-const char test17_d[] = {1, 2, 3, 4};
+const char test17_d[] = {1, 2, 3, 4}; // Like test17_c but not NUL-terminated.
typedef int __attribute__((vector_size(16))) IntVector;
struct Aggregate { int n; char c; };
enum Enum { EnumValue1, EnumValue2 };
@@ -178,9 +178,10 @@
ASSERT(!OPT("abcd"));
// In these cases, the strlen is non-constant, but the __builtin_constant_p
// is 0: the array size is not an ICE but is foldable.
- ASSERT(!OPT(test17_c)); // expected-warning {{folding}}
- ASSERT(!OPT(&test17_c[0])); // expected-warning {{folding}}
- ASSERT(!OPT((char*)test17_c)); // expected-warning {{folding}}
+ ASSERT(!OPT(test17_c));
+ ASSERT(!OPT(&test17_c[0]));
+ ASSERT(!OPT((char*)test17_c));
+ // NOTE: test17_d is not NUL-termintated, so calling strlen on it is UB.
ASSERT(!OPT(test17_d)); // expected-warning {{folding}}
ASSERT(!OPT(&test17_d[0])); // expected-warning {{folding}}
ASSERT(!OPT((char*)test17_d)); // expected-warning {{folding}}
Index: clang/test/CodeGen/const-init.c
===================================================================
--- clang/test/CodeGen/const-init.c
+++ clang/test/CodeGen/const-init.c
@@ -190,3 +190,28 @@
struct { const float *floats; } compoundliteral = {
(float[1]) { 0.1, },
};
+
+struct PR4517_foo {
+ int x;
+};
+struct PR4517_bar {
+ struct PR4517_foo foo;
+};
+const struct PR4517_foo my_foo = {.x = 42};
+struct PR4517_bar my_bar = {.foo = my_foo};
+struct PR4517_bar my_bar2 = (struct PR4517_bar){.foo = my_foo};
+struct PR4517_bar my_bar3 = {my_foo};
+struct PR4517_bar my_bar4 = (struct PR4517_bar){my_foo};
+// CHECK: @my_foo = constant %struct.PR4517_foo { i32 42 }, align 4
+// CHECK: @my_bar = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+// CHECK: @my_bar2 = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+// CHECK: @my_bar3 = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+// CHECK: @my_bar4 = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+const int PR4517_arrc[2] = {41, 42};
+int PR4517_x = PR4517_arrc[1];
+const int PR4517_idx = 1;
+int PR4517_x2 = PR4517_arrc[PR4517_idx];
+// CHECK: @PR4517_arrc = constant [2 x i32] [i32 41, i32 42], align 4
+// CHECK: @PR4517_x = global i32 42, align 4
+// CHECK: @PR4517_idx = constant i32 1, align 4
+// CHECK: @PR4517_x2 = global i32 42, align 4
Index: clang/test/CodeGen/builtin-constant-p.c
===================================================================
--- clang/test/CodeGen/builtin-constant-p.c
+++ clang/test/CodeGen/builtin-constant-p.c
@@ -76,7 +76,7 @@
int test7(void) {
// CHECK-LABEL: test7
- // CHECK: call i1 @llvm.is.constant.i32
+ // CHECK: ret i32 1
return __builtin_constant_p(c_arr[2]);
}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -15218,14 +15218,6 @@
return true;
}
- // FIXME: Evaluating values of large array and record types can cause
- // performance problems. Only do so in C++11 for now.
- if (Exp->isPRValue() &&
- (Exp->getType()->isArrayType() || Exp->getType()->isRecordType()) &&
- !Ctx.getLangOpts().CPlusPlus11) {
- IsConst = false;
- return true;
- }
return false;
}
@@ -15467,12 +15459,6 @@
return Name;
});
- // FIXME: Evaluating initializers for large array and record types can cause
- // performance problems. Only do so in C++11 for now.
- if (isPRValue() && (getType()->isArrayType() || getType()->isRecordType()) &&
- !Ctx.getLangOpts().CPlusPlus11)
- return false;
-
Expr::EvalStatus EStatus;
EStatus.Diag = &Notes;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -179,6 +179,9 @@
_Generic(i, int : 0, const int : 1); // Warns about unreachable code, the
// result is 0, not 1.
_Generic(typeof(i), int : 0, const int : 1); // Result is 1, not 0.
+- ``structs``, ``unions``, and ``arrays`` that are const may now be used as
+ constant expressions. This change is more consistent with the behavior of
+ GCC.
C2x Feature Support
^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits