[PATCH] D58069: [Sema] Mark GNU compound literal array init as an rvalue.
Eli Friedman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 11 12:38:33 PST 2019
efriedma created this revision.
efriedma added a reviewer: rsmith.
Herald added a project: clang.
Basically the same issue as string init, except it didn't really have any visible consequences before I removed the implicit lvalue-to-rvalue conversion from CodeGen.
While I'm here, a couple minor drive-by cleanups: IgnoreParens never returns a ConstantExpr, and there was a potential crash with string init involving a ChooseExpr.
The analyzer test change maybe indicates we could simplify the analyzer code a little with this fix? Apparently a hack was added to support lvalues in initializers in r315750, but I'm not really familiar with the relevant code.
Fixes regression reported in the kernel build at https://bugs.llvm.org/show_bug.cgi?id=40430#c6 .
Repository:
rC Clang
https://reviews.llvm.org/D58069
Files:
lib/Sema/SemaInit.cpp
test/Analysis/compound-literals.c
test/CodeGen/compound-literal.c
Index: test/CodeGen/compound-literal.c
===================================================================
--- test/CodeGen/compound-literal.c
+++ test/CodeGen/compound-literal.c
@@ -11,6 +11,11 @@
typedef int v4i32 __attribute((vector_size(16)));
v4i32 *y = &(v4i32){1,2,3,4};
+// Check generated code for GNU constant array init from compound literal,
+// for a global variable.
+// CHECK: @compound_array = global [8 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8]
+int compound_array[] = __extension__(__builtin_choose_expr(0, 0, _Generic(1, int: (int[]){1, 2, 3, 4, 5, 6, 7, 8})));
+
void xxx() {
int* a = &(int){1};
struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
@@ -82,3 +87,13 @@
const void *b = MyCLH;
return a == b;
}
+
+// Check generated code for GNU constant array init from compound literal,
+// for a local variable.
+// CHECK-LABEL: define i32 @compound_array_fn()
+// CHECK: [[COMPOUND_ARRAY:%.*]] = alloca [8 x i32]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}, i64 32, i1 false)
+int compound_array_fn() {
+ int compound_array[] = (int[]){1,2,3,4,5,6,7,8};
+ return compound_array[0];
+}
Index: test/Analysis/compound-literals.c
===================================================================
--- test/Analysis/compound-literals.c
+++ test/Analysis/compound-literals.c
@@ -4,6 +4,5 @@
// pr28449: Used to crash.
void foo(void) {
static const unsigned short array[] = (const unsigned short[]){0x0F00};
- // FIXME: Should be true.
- clang_analyzer_eval(array[0] == 0x0F00); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(array[0] == 0x0F00); // expected-warning{{TRUE}}
}
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -153,11 +153,33 @@
E = UO->getSubExpr();
else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E))
E = GSE->getResultExpr();
+ else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E))
+ E = CE->getChosenSubExpr();
else
llvm_unreachable("unexpected expr in string literal init");
}
}
+/// Fix a compound literal initializing an array so it's correctly marked
+/// as an rvalue.
+static void updateGNUCompoundLiteralRValue(Expr *E) {
+ while (true) {
+ E->setValueKind(VK_RValue);
+ if (isa<CompoundLiteralExpr>(E))
+ break;
+ else if (ParenExpr *PE = dyn_cast<ParenExpr>(E))
+ E = PE->getSubExpr();
+ else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
+ E = UO->getSubExpr();
+ else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E))
+ E = GSE->getResultExpr();
+ else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E))
+ E = CE->getChosenSubExpr();
+ else
+ llvm_unreachable("unexpected expr in array compound literal init");
+ }
+}
+
static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
Sema &S) {
// Get the length of the string as parsed.
@@ -5542,8 +5564,7 @@
// array from a compound literal that creates an array of the same
// type, so long as the initializer has no side effects.
if (!S.getLangOpts().CPlusPlus && Initializer &&
- (isa<ConstantExpr>(Initializer->IgnoreParens()) ||
- isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) &&
+ isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) &&
Initializer->getType()->isArrayType()) {
const ArrayType *SourceAT
= Context.getAsArrayType(Initializer->getType());
@@ -7956,6 +7977,7 @@
S.Diag(Kind.getLocation(), diag::ext_array_init_copy)
<< Step->Type << CurInit.get()->getType()
<< CurInit.get()->getSourceRange();
+ updateGNUCompoundLiteralRValue(CurInit.get());
LLVM_FALLTHROUGH;
case SK_ArrayInit:
// If the destination type is an incomplete array type, update the
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58069.186309.patch
Type: text/x-patch
Size: 3932 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190211/ac448728/attachment-0001.bin>
More information about the cfe-commits
mailing list