summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorEli Friedman <efriedma@quicinc.com>2019-02-11 22:54:27 +0000
committerEli Friedman <efriedma@quicinc.com>2019-02-11 22:54:27 +0000
commit88fccbdea70d988f360baa7b6b0cea618518ee07 (patch)
tree47d8a4b14aef018c2a22fabf8ac0586cfb13bfda /clang/lib/Sema/SemaInit.cpp
parent9d5a089bf544e5d7cd815591706afb2ea3784c10 (diff)
downloadbcm5719-llvm-88fccbdea70d988f360baa7b6b0cea618518ee07.tar.gz
bcm5719-llvm-88fccbdea70d988f360baa7b6b0cea618518ee07.zip
[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
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp40
1 files changed, 33 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 59aa42078b5..20ebaf5460f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -145,16 +145,42 @@ static void updateStringLiteralType(Expr *E, QualType Ty) {
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 @@ void InitializationSequence::InitializeFrom(Sema &S,
// 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 @@ ExprResult InitializationSequence::Perform(Sema &S,
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
OpenPOWER on IntegriCloud