[Sema] Mark GNU compound literal array init as an rvalue.
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 .
Differential Revision: https://reviews.llvm.org/D58069
llvm-svn: 353762
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 59aa420..20ebaf5 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -145,16 +145,42 @@
while (true) {
E->setType(Ty);
E->setValueKind(VK_RValue);
- if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E))
+ if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) {
break;
- else if (ParenExpr *PE = dyn_cast<ParenExpr>(E))
+ } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
E = PE->getSubExpr();
- else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
+ } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+ assert(UO->getOpcode() == UO_Extension);
E = UO->getSubExpr();
- else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E))
+ } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
E = GSE->getResultExpr();
- else
+ } 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)) {
+ assert(UO->getOpcode() == UO_Extension);
+ 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");
+ }
}
}
@@ -5542,8 +5568,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 +7981,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