diff options
author | Eli Friedman <efriedma@quicinc.com> | 2019-02-11 22:54:27 +0000 |
---|---|---|
committer | Eli Friedman <efriedma@quicinc.com> | 2019-02-11 22:54:27 +0000 |
commit | 88fccbdea70d988f360baa7b6b0cea618518ee07 (patch) | |
tree | 47d8a4b14aef018c2a22fabf8ac0586cfb13bfda /clang/lib/Sema/SemaInit.cpp | |
parent | 9d5a089bf544e5d7cd815591706afb2ea3784c10 (diff) | |
download | bcm5719-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.cpp | 40 |
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 |