diff options
Diffstat (limited to 'lib/Sema/SemaPseudoObject.cpp')
-rw-r--r-- | lib/Sema/SemaPseudoObject.cpp | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index 58980be64a30..4484e9b3513b 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -132,7 +132,8 @@ namespace { uop->getType(), uop->getValueKind(), uop->getObjectKind(), - uop->getOperatorLoc()); + uop->getOperatorLoc(), + uop->canOverflow()); } if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { @@ -189,11 +190,12 @@ namespace { Sema &S; unsigned ResultIndex; SourceLocation GenericLoc; + bool IsUnique; SmallVector<Expr *, 4> Semantics; - PseudoOpBuilder(Sema &S, SourceLocation genericLoc) + PseudoOpBuilder(Sema &S, SourceLocation genericLoc, bool IsUnique) : S(S), ResultIndex(PseudoObjectExpr::NoResult), - GenericLoc(genericLoc) {} + GenericLoc(genericLoc), IsUnique(IsUnique) {} virtual ~PseudoOpBuilder() {} @@ -207,6 +209,9 @@ namespace { assert(ResultIndex == PseudoObjectExpr::NoResult); ResultIndex = Semantics.size(); Semantics.push_back(resultExpr); + // An OVE is not unique if it is used as the result expression. + if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back())) + OVE->setIsUnique(false); } ExprResult buildRValueOperation(Expr *op); @@ -226,6 +231,9 @@ namespace { void setResultToLastSemantic() { assert(ResultIndex == PseudoObjectExpr::NoResult); ResultIndex = Semantics.size() - 1; + // An OVE is not unique if it is used as the result expression. + if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back())) + OVE->setIsUnique(false); } /// Return true if assignments have a non-void result. @@ -245,7 +253,7 @@ namespace { virtual ExprResult buildGet() = 0; virtual ExprResult buildSet(Expr *, SourceLocation, bool captureSetValueAsResult) = 0; - /// \brief Should the result of an assignment be the formal result of the + /// Should the result of an assignment be the formal result of the /// setter call or the value that was passed to the setter? /// /// Different pseudo-object language features use different language rules @@ -273,10 +281,10 @@ namespace { Selector GetterSelector; public: - ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) : - PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr), - SyntacticRefExpr(nullptr), InstanceReceiver(nullptr), Getter(nullptr), - Setter(nullptr) { + ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr, bool IsUnique) + : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique), + RefExpr(refExpr), SyntacticRefExpr(nullptr), + InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) { } ExprResult buildRValueOperation(Expr *op); @@ -313,11 +321,10 @@ namespace { Selector AtIndexSetterSelector; public: - ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) : - PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), - RefExpr(refExpr), - InstanceBase(nullptr), InstanceKey(nullptr), - AtIndexGetter(nullptr), AtIndexSetter(nullptr) {} + ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr, bool IsUnique) + : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique), + RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr), + AtIndexGetter(nullptr), AtIndexSetter(nullptr) {} ExprResult buildRValueOperation(Expr *op); ExprResult buildAssignmentOperation(Scope *Sc, @@ -341,11 +348,11 @@ namespace { MSPropertyRefExpr *getBaseMSProperty(MSPropertySubscriptExpr *E); public: - MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) : - PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), - RefExpr(refExpr), InstanceBase(nullptr) {} - MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr) - : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), + MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr, bool IsUnique) + : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique), + RefExpr(refExpr), InstanceBase(nullptr) {} + MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr, bool IsUnique) + : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique), InstanceBase(nullptr) { RefExpr = getBaseMSProperty(refExpr); } @@ -364,7 +371,9 @@ OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) { new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(), e->getValueKind(), e->getObjectKind(), e); - + if (IsUnique) + captured->setIsUnique(true); + // Make sure we bind that in the semantics. addSemanticExpr(captured); return captured; @@ -396,6 +405,8 @@ OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) { if (e == Semantics[index]) break; } ResultIndex = index; + // An OVE is not unique if it is used as the result expression. + cast<OpaqueValueExpr>(e)->setIsUnique(false); return cast<OpaqueValueExpr>(e); } @@ -527,9 +538,12 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) setResultToLastSemantic(); - UnaryOperator *syntactic = - new (S.Context) UnaryOperator(syntacticOp, opcode, resultType, - VK_LValue, OK_Ordinary, opcLoc); + UnaryOperator *syntactic = new (S.Context) UnaryOperator( + syntacticOp, opcode, resultType, VK_LValue, OK_Ordinary, opcLoc, + !resultType->isDependentType() + ? S.Context.getTypeSize(resultType) >= + S.Context.getTypeSize(S.Context.IntTy) + : false); return complete(syntactic); } @@ -961,11 +975,11 @@ ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, } ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) { - if (isWeakProperty() && + if (isWeakProperty() && !S.isUnevaluatedContext() && !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, SyntacticForm->getLocStart())) - S.recordUseOfEvaluatedWeak(SyntacticRefExpr, - SyntacticRefExpr->isMessagingGetter()); + S.getCurFunction()->recordUseOfWeak(SyntacticRefExpr, + SyntacticRefExpr->isMessagingGetter()); return PseudoOpBuilder::complete(SyntacticForm); } @@ -1524,20 +1538,20 @@ ExprResult Sema::checkPseudoObjectRValue(Expr *E) { Expr *opaqueRef = E->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { - ObjCPropertyOpBuilder builder(*this, refExpr); + ObjCPropertyOpBuilder builder(*this, refExpr, true); return builder.buildRValueOperation(E); } else if (ObjCSubscriptRefExpr *refExpr = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { - ObjCSubscriptOpBuilder builder(*this, refExpr); + ObjCSubscriptOpBuilder builder(*this, refExpr, true); return builder.buildRValueOperation(E); } else if (MSPropertyRefExpr *refExpr = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr); + MSPropertyOpBuilder builder(*this, refExpr, true); return builder.buildRValueOperation(E); } else if (MSPropertySubscriptExpr *RefExpr = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { - MSPropertyOpBuilder Builder(*this, RefExpr); + MSPropertyOpBuilder Builder(*this, RefExpr, true); return Builder.buildRValueOperation(E); } else { llvm_unreachable("unknown pseudo-object kind!"); @@ -1550,24 +1564,24 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, // Do nothing if the operand is dependent. if (op->isTypeDependent()) return new (Context) UnaryOperator(op, opcode, Context.DependentTy, - VK_RValue, OK_Ordinary, opcLoc); + VK_RValue, OK_Ordinary, opcLoc, false); assert(UnaryOperator::isIncrementDecrementOp(opcode)); Expr *opaqueRef = op->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { - ObjCPropertyOpBuilder builder(*this, refExpr); + ObjCPropertyOpBuilder builder(*this, refExpr, false); return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) { Diag(opcLoc, diag::err_illegal_container_subscripting_op); return ExprError(); } else if (MSPropertyRefExpr *refExpr = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr); + MSPropertyOpBuilder builder(*this, refExpr, false); return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else if (MSPropertySubscriptExpr *RefExpr = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { - MSPropertyOpBuilder Builder(*this, RefExpr); + MSPropertyOpBuilder Builder(*this, RefExpr, false); return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else { llvm_unreachable("unknown pseudo-object kind!"); @@ -1590,22 +1604,23 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, RHS = result.get(); } + bool IsSimpleAssign = opcode == BO_Assign; Expr *opaqueRef = LHS->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { - ObjCPropertyOpBuilder builder(*this, refExpr); + ObjCPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign); return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (ObjCSubscriptRefExpr *refExpr = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { - ObjCSubscriptOpBuilder builder(*this, refExpr); + ObjCSubscriptOpBuilder builder(*this, refExpr, IsSimpleAssign); return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (MSPropertyRefExpr *refExpr = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr); + MSPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign); return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (MSPropertySubscriptExpr *RefExpr = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { - MSPropertyOpBuilder Builder(*this, RefExpr); + MSPropertyOpBuilder Builder(*this, RefExpr, IsSimpleAssign); return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else { llvm_unreachable("unknown pseudo-object kind!"); @@ -1633,9 +1648,9 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { Expr *syntax = E->getSyntacticForm(); if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) { Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); - return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(), - uop->getValueKind(), uop->getObjectKind(), - uop->getOperatorLoc()); + return new (Context) UnaryOperator( + op, uop->getOpcode(), uop->getType(), uop->getValueKind(), + uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow()); } else if (CompoundAssignOperator *cop = dyn_cast<CompoundAssignOperator>(syntax)) { Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); |