diff options
Diffstat (limited to 'clang/lib/Sema/SemaPseudoObject.cpp')
-rw-r--r-- | clang/lib/Sema/SemaPseudoObject.cpp | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index fec97488f53..a7029fa07c6 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -406,19 +406,27 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, BinaryOperatorKind opcode, Expr *LHS, Expr *RHS) { assert(BinaryOperator::isAssignmentOp(opcode)); - - // Recover from user error - if (isa<UnresolvedLookupExpr>(RHS)) - return ExprError(); Expr *syntacticLHS = rebuildAndCaptureObject(LHS); OpaqueValueExpr *capturedRHS = capture(RHS); + // In some very specific cases, semantic analysis of the RHS as an + // expression may require it to be rewritten. In these cases, we + // cannot safely keep the OVE around. Fortunately, we don't really + // need to: we don't use this particular OVE in multiple places, and + // no clients rely that closely on matching up expressions in the + // semantic expression with expressions from the syntactic form. + Expr *semanticRHS = capturedRHS; + if (RHS->hasPlaceholderType() || isa<InitListExpr>(RHS)) { + semanticRHS = RHS; + Semantics.pop_back(); + } + Expr *syntactic; ExprResult result; if (opcode == BO_Assign) { - result = capturedRHS; + result = semanticRHS; syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS, opcode, capturedRHS->getType(), capturedRHS->getValueKind(), @@ -430,8 +438,7 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, // Build an ordinary, non-compound operation. BinaryOperatorKind nonCompound = BinaryOperator::getOpForCompoundAssignment(opcode); - result = S.BuildBinOp(Sc, opcLoc, nonCompound, - opLHS.get(), capturedRHS); + result = S.BuildBinOp(Sc, opcLoc, nonCompound, opLHS.get(), semanticRHS); if (result.isInvalid()) return ExprError(); syntactic = @@ -745,16 +752,6 @@ ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, op = opResult.get(); assert(op && "successful assignment left argument invalid?"); } - else if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(op)) { - Expr *Initializer = OVE->getSourceExpr(); - // passing C++11 style initialized temporaries to objc++ properties - // requires special treatment by removing OpaqueValueExpr so type - // conversion takes place and adding the OpaqueValueExpr later on. - if (isa<InitListExpr>(Initializer) && - Initializer->getType()->isVoidType()) { - op = Initializer; - } - } } // Arguments. |