diff options
| author | Akira Hatanaka <ahatanaka@apple.com> | 2018-03-20 01:47:58 +0000 |
|---|---|---|
| committer | Akira Hatanaka <ahatanaka@apple.com> | 2018-03-20 01:47:58 +0000 |
| commit | 797afe3a4ed475d26786a31ede9ac6a9e790608d (patch) | |
| tree | 4f2914b8f20f3294ead7d5335e2af0e2b2aed277 /clang/lib | |
| parent | cbd498ac10427778a6133b9dc3a78c3a5e9ec6cd (diff) | |
| download | bcm5719-llvm-797afe3a4ed475d26786a31ede9ac6a9e790608d.tar.gz bcm5719-llvm-797afe3a4ed475d26786a31ede9ac6a9e790608d.zip | |
[CodeGen] Ignore OpaqueValueExprs that are unique references to their
source expressions when iterating over a PseudoObjectExpr's semantic
subexpression list.
Previously the loop in emitPseudoObjectExpr would emit the IR for each
OpaqueValueExpr that was in a PseudoObjectExpr's semantic-form
expression list and use the result when the OpaqueValueExpr later
appeared in other expressions. This caused an assertion failure when
AggExprEmitter tried to copy the result of an OpaqueValueExpr and the
copied type didn't have trivial copy/move constructors or assignment
operators.
This patch adds flag IsUnique to OpaqueValueExpr which indicates it is a
unique reference to its source expression (it is not used in multiple
places). The loop in emitPseudoObjectExpr ignores OpaqueValueExprs that
are unique and CodeGen visitors simply traverse the source expressions
of such OpaqueValueExprs.
rdar://problem/34363596
Differential Revision: https://reviews.llvm.org/D39562
llvm-svn: 327939
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 36 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 26 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaPseudoObject.cpp | 67 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 1 |
8 files changed, 93 insertions, 54 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index ddf4705b20f..35122265f7c 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4167,7 +4167,35 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) { assert(OpaqueValueMappingData::shouldBindAsLValue(e)); - return getOpaqueLValueMapping(e); + return getOrCreateOpaqueLValueMapping(e); +} + +LValue +CodeGenFunction::getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e) { + assert(OpaqueValueMapping::shouldBindAsLValue(e)); + + llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator + it = OpaqueLValues.find(e); + + if (it != OpaqueLValues.end()) + return it->second; + + assert(e->isUnique() && "LValue for a nonunique OVE hasn't been emitted"); + return EmitLValue(e->getSourceExpr()); +} + +RValue +CodeGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) { + assert(!OpaqueValueMapping::shouldBindAsLValue(e)); + + llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator + it = OpaqueRValues.find(e); + + if (it != OpaqueRValues.end()) + return it->second; + + assert(e->isUnique() && "RValue for a nonunique OVE hasn't been emitted"); + return EmitAnyExpr(e->getSourceExpr()); } RValue CodeGenFunction::EmitRValueForField(LValue LV, @@ -4719,6 +4747,12 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF, // If this semantic expression is an opaque value, bind it // to the result of its source expression. if (const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) { + // Skip unique OVEs. + if (ov->isUnique()) { + assert(ov != resultExpr && + "A unique OVE cannot be used as the result expression"); + continue; + } // If this is the result expression, we may need to evaluate // directly into the slot. diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 371c14cde01..959086891c8 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -630,7 +630,11 @@ void AggExprEmitter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E){ } void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) { - EmitFinalDestCopy(e->getType(), CGF.getOpaqueLValueMapping(e)); + // If this is a unique OVE, just visit its source expression. + if (e->isUnique()) + Visit(e->getSourceExpr()); + else + EmitFinalDestCopy(e->getType(), CGF.getOrCreateOpaqueLValueMapping(e)); } void diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 9094d3f8a91..ededfbb4945 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -155,8 +155,9 @@ public: } ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { if (E->isGLValue()) - return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc()); - return CGF.getOpaqueRValueMapping(E).getComplexVal(); + return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), + E->getExprLoc()); + return CGF.getOrCreateOpaqueRValueMapping(E).getComplexVal(); } ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 2a0dd4a4104..bed37d624e0 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -422,10 +422,11 @@ public: Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) { if (E->isGLValue()) - return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc()); + return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), + E->getExprLoc()); // Otherwise, assume the mapping is the scalar directly. - return CGF.getOpaqueRValueMapping(E).getScalarVal(); + return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal(); } Value *emitConstant(const CodeGenFunction::ConstantEmission &Constant, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5852788e296..709e7f4ad8d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2148,27 +2148,13 @@ public: return it->second; } - /// getOpaqueLValueMapping - Given an opaque value expression (which - /// must be mapped to an l-value), return its mapping. - const LValue &getOpaqueLValueMapping(const OpaqueValueExpr *e) { - assert(OpaqueValueMapping::shouldBindAsLValue(e)); - - llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator - it = OpaqueLValues.find(e); - assert(it != OpaqueLValues.end() && "no mapping for opaque value!"); - return it->second; - } - - /// getOpaqueRValueMapping - Given an opaque value expression (which - /// must be mapped to an r-value), return its mapping. - const RValue &getOpaqueRValueMapping(const OpaqueValueExpr *e) { - assert(!OpaqueValueMapping::shouldBindAsLValue(e)); + /// Given an opaque value expression, return its LValue mapping if it exists, + /// otherwise create one. + LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e); - llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator - it = OpaqueRValues.find(e); - assert(it != OpaqueRValues.end() && "no mapping for opaque value!"); - return it->second; - } + /// Given an opaque value expression, return its RValue mapping if it exists, + /// otherwise create one. + RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e); /// Get the index of the current ArrayInitLoopExpr, if any. llvm::Value *getArrayInitIndex() { return ArrayInitIndex; } diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index 8a671b14872..a267670cc9b 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -190,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() {} @@ -208,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); @@ -227,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. @@ -274,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); @@ -314,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, @@ -342,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); } @@ -365,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; @@ -397,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); } @@ -1528,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!"); @@ -1560,18 +1570,18 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, 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!"); @@ -1594,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!"); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 4938b0e9026..a1ae6a42c47 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1667,6 +1667,7 @@ void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); E->SourceExpr = Record.readSubExpr(); E->Loc = ReadSourceLocation(); + E->setIsUnique(Record.readInt()); } void ASTStmtReader::VisitTypoExpr(TypoExpr *E) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 6fd03725d43..0a02d1db86f 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1699,6 +1699,7 @@ void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); Record.AddStmt(E->getSourceExpr()); Record.AddSourceLocation(E->getLocation()); + Record.push_back(E->isUnique()); Code = serialization::EXPR_OPAQUE_VALUE; } |

