r272296 - [Temporary] Add an ExprWithCleanups for each C++ MaterializeTemporaryExpr.
Tim Shen via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 9 12:54:46 PDT 2016
Author: timshen
Date: Thu Jun 9 14:54:46 2016
New Revision: 272296
URL: http://llvm.org/viewvc/llvm-project?rev=272296&view=rev
Log:
[Temporary] Add an ExprWithCleanups for each C++ MaterializeTemporaryExpr.
These ExprWithCleanups are added for holding a RunCleanupsScope not
for destructor calls; rather, they are for lifetime marks. This requires
ExprWithCleanups to keep a bit to indicate whether it have cleanups with
side effects (e.g. dtor calls).
Differential Revision: http://reviews.llvm.org/D20498
Added:
cfe/trunk/include/clang/Sema/CleanupInfo.h
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/include/clang/Sema/ScopeInfo.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprCXX.cpp
cfe/trunk/lib/Analysis/Consumed.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaCast.cpp
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Thu Jun 9 14:54:46 2016
@@ -2877,7 +2877,8 @@ private:
Stmt *SubExpr;
ExprWithCleanups(EmptyShell, unsigned NumObjects);
- ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
+ ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
+ ArrayRef<CleanupObject> Objects);
friend TrailingObjects;
friend class ASTStmtReader;
@@ -2887,6 +2888,7 @@ public:
unsigned numObjects);
static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
+ bool CleanupsHaveSideEffects,
ArrayRef<CleanupObject> objects);
ArrayRef<CleanupObject> getObjects() const {
@@ -2903,6 +2905,9 @@ public:
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+ bool cleanupsHaveSideEffects() const {
+ return ExprWithCleanupsBits.CleanupsHaveSideEffects;
+ }
/// As with any mutator of the AST, be very careful
/// when modifying an existing AST to preserve its invariants.
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Thu Jun 9 14:54:46 2016
@@ -192,7 +192,10 @@ protected:
unsigned : NumExprBits;
- unsigned NumObjects : 32 - NumExprBits;
+ // When false, it must not have side effects.
+ bool CleanupsHaveSideEffects : 1;
+
+ unsigned NumObjects : 32 - 1 - NumExprBits;
};
class PseudoObjectExprBitfields {
Added: cfe/trunk/include/clang/Sema/CleanupInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CleanupInfo.h?rev=272296&view=auto
==============================================================================
--- cfe/trunk/include/clang/Sema/CleanupInfo.h (added)
+++ cfe/trunk/include/clang/Sema/CleanupInfo.h Thu Jun 9 14:54:46 2016
@@ -0,0 +1,47 @@
+//===--- CleanupInfo.cpp - Cleanup Control in Sema ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a set of operations on whether generating an
+// ExprWithCleanups in a full expression.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_CLEANUP_INFO_H
+#define LLVM_CLANG_SEMA_CLEANUP_INFO_H
+
+namespace clang {
+
+class CleanupInfo {
+ bool ExprNeedsCleanups = false;
+ bool CleanupsHaveSideEffects = false;
+
+public:
+ bool exprNeedsCleanups() const { return ExprNeedsCleanups; }
+
+ bool cleanupsHaveSideEffects() const { return CleanupsHaveSideEffects; }
+
+ void setExprNeedsCleanups(bool SideEffects) {
+ ExprNeedsCleanups = true;
+ CleanupsHaveSideEffects |= SideEffects;
+ }
+
+ void reset() {
+ ExprNeedsCleanups = false;
+ CleanupsHaveSideEffects = false;
+ }
+
+ void mergeFrom(CleanupInfo Rhs) {
+ ExprNeedsCleanups |= Rhs.ExprNeedsCleanups;
+ CleanupsHaveSideEffects |= Rhs.CleanupsHaveSideEffects;
+ }
+};
+
+} // end namespace clang
+
+#endif
Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Thu Jun 9 14:54:46 2016
@@ -19,6 +19,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Sema/CleanupInfo.h"
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
@@ -682,7 +683,7 @@ public:
bool ExplicitParams;
/// \brief Whether any of the capture expressions requires cleanups.
- bool ExprNeedsCleanups;
+ CleanupInfo Cleanup;
/// \brief Whether the lambda contains an unexpanded parameter pack.
bool ContainsUnexpandedParameterPack;
@@ -730,7 +731,7 @@ public:
LambdaScopeInfo(DiagnosticsEngine &Diag)
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
- ExplicitParams(false), ExprNeedsCleanups(false),
+ ExplicitParams(false), Cleanup{},
ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0),
GLTemplateParameterList(nullptr) {
Kind = SK_Lambda;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 9 14:54:46 2016
@@ -34,6 +34,7 @@
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TypeTraits.h"
#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/CleanupInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/IdentifierResolver.h"
@@ -440,9 +441,8 @@ public:
/// if Sema is already doing so, which would cause infinite recursions.
bool IsBuildingRecoveryCallExpr;
- /// ExprNeedsCleanups - True if the current evaluation context
- /// requires cleanups to be run at its conclusion.
- bool ExprNeedsCleanups;
+ /// Used to control the generation of ExprWithCleanups.
+ CleanupInfo Cleanup;
/// ExprCleanupObjects - This is the stack of objects requiring
/// cleanup that are created by the current full expression. The
@@ -830,7 +830,7 @@ public:
ExpressionEvaluationContext Context;
/// \brief Whether the enclosing context needed a cleanup.
- bool ParentNeedsCleanups;
+ CleanupInfo ParentCleanup;
/// \brief Whether we are in a decltype expression.
bool IsDecltype;
@@ -871,10 +871,10 @@ public:
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumCleanupObjects,
- bool ParentNeedsCleanups,
+ CleanupInfo ParentCleanup,
Decl *ManglingContextDecl,
bool IsDecltype)
- : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
+ : Context(Context), ParentCleanup(ParentCleanup),
IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
NumTypos(0),
ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
@@ -4872,6 +4872,10 @@ public:
Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt);
ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr);
+ MaterializeTemporaryExpr *
+ CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
+ bool BoundToLvalueReference);
+
ExprResult ActOnFinishFullExpr(Expr *Expr) {
return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
: SourceLocation());
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Jun 9 14:54:46 2016
@@ -2890,7 +2890,6 @@ bool Expr::HasSideEffects(const ASTConte
case CXXThrowExprClass:
case CXXNewExprClass:
case CXXDeleteExprClass:
- case ExprWithCleanupsClass:
case CoawaitExprClass:
case CoyieldExprClass:
// These always have a side-effect.
@@ -2903,6 +2902,12 @@ bool Expr::HasSideEffects(const ASTConte
return Finder.hasSideEffects();
}
+ case ExprWithCleanupsClass:
+ if (IncludePossibleEffects)
+ if (cast<ExprWithCleanups>(this)->cleanupsHaveSideEffects())
+ return true;
+ break;
+
case ParenExprClass:
case ArraySubscriptExprClass:
case OMPArraySectionExprClass:
Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Thu Jun 9 14:54:46 2016
@@ -1039,6 +1039,7 @@ bool LambdaExpr::isMutable() const {
}
ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
+ bool CleanupsHaveSideEffects,
ArrayRef<CleanupObject> objects)
: Expr(ExprWithCleanupsClass, subexpr->getType(),
subexpr->getValueKind(), subexpr->getObjectKind(),
@@ -1046,16 +1047,19 @@ ExprWithCleanups::ExprWithCleanups(Expr
subexpr->isInstantiationDependent(),
subexpr->containsUnexpandedParameterPack()),
SubExpr(subexpr) {
+ ExprWithCleanupsBits.CleanupsHaveSideEffects = CleanupsHaveSideEffects;
ExprWithCleanupsBits.NumObjects = objects.size();
for (unsigned i = 0, e = objects.size(); i != e; ++i)
getTrailingObjects<CleanupObject>()[i] = objects[i];
}
ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr,
+ bool CleanupsHaveSideEffects,
ArrayRef<CleanupObject> objects) {
void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(objects.size()),
llvm::alignOf<ExprWithCleanups>());
- return new (buffer) ExprWithCleanups(subexpr, objects);
+ return new (buffer)
+ ExprWithCleanups(subexpr, CleanupsHaveSideEffects, objects);
}
ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects)
Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Jun 9 14:54:46 2016
@@ -466,9 +466,15 @@ class ConsumedStmtVisitor : public Const
MapType PropagationMap;
InfoEntry findInfo(const Expr *E) {
+ if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
+ if (!Cleanups->cleanupsHaveSideEffects())
+ E = Cleanups->getSubExpr();
return PropagationMap.find(E->IgnoreParens());
}
ConstInfoEntry findInfo(const Expr *E) const {
+ if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
+ if (!Cleanups->cleanupsHaveSideEffects())
+ E = Cleanups->getSubExpr();
return PropagationMap.find(E->IgnoreParens());
}
void insertInfo(const Expr *E, const PropagationInfo &PI) {
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Jun 9 14:54:46 2016
@@ -764,6 +764,12 @@ public:
return Visit(DIE->getExpr());
}
+ llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E) {
+ if (!E->cleanupsHaveSideEffects())
+ return Visit(E->getSubExpr());
+ return nullptr;
+ }
+
llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
return Visit(E->GetTemporaryExpr());
}
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Jun 9 14:54:46 2016
@@ -88,7 +88,7 @@ Sema::Sema(Preprocessor &pp, ASTContext
ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
VisContext(nullptr),
IsBuildingRecoveryCallExpr(false),
- ExprNeedsCleanups(false), LateTemplateParser(nullptr),
+ Cleanup{}, LateTemplateParser(nullptr),
LateTemplateParserCleanup(nullptr),
OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr),
CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
@@ -124,7 +124,8 @@ Sema::Sema(Preprocessor &pp, ASTContext
// Tell diagnostics how to render things from the AST library.
Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context);
- ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, false, nullptr, false);
+ ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, CleanupInfo{}, nullptr,
+ false);
FunctionScopes.push_back(new FunctionScopeInfo(Diags));
Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Thu Jun 9 14:54:46 2016
@@ -641,8 +641,8 @@ void CastOperation::CheckDynamicCast() {
// If we're dynamic_casting from a prvalue to an rvalue reference, we need
// to materialize the prvalue before we bind the reference to it.
if (SrcExpr.get()->isRValue())
- SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
- SrcType, SrcExpr.get(), /*IsLValueReference*/false);
+ SrcExpr = Self.CreateMaterializeTemporaryExpr(
+ SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
SrcPointee = SrcType;
}
@@ -1649,8 +1649,8 @@ static TryCastResult TryConstCast(Sema &
if (NeedToMaterializeTemporary)
// This is a const_cast from a class prvalue to an rvalue reference type.
// Materialize a temporary to store the result of the conversion.
- SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
- SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
+ SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
+ /*IsLValueReference*/ false);
return TC_Success;
}
Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Thu Jun 9 14:54:46 2016
@@ -244,7 +244,7 @@ ExprResult Sema::BuildCoawaitExpr(Source
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (E->getValueKind() == VK_RValue)
- E = new (Context) MaterializeTemporaryExpr(E->getType(), E, true);
+ E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
// Build the await_ready, await_suspend, await_resume calls.
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
@@ -311,7 +311,7 @@ ExprResult Sema::BuildCoyieldExpr(Source
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (E->getValueKind() == VK_RValue)
- E = new (Context) MaterializeTemporaryExpr(E->getType(), E, true);
+ E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
// Build the await_ready, await_suspend, await_resume calls.
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jun 9 14:54:46 2016
@@ -11648,7 +11648,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
assert(ExprCleanupObjects.size() ==
ExprEvalContexts.back().NumCleanupObjects &&
"Leftover temporaries in function");
- assert(!ExprNeedsCleanups && "Unaccounted cleanups in function");
+ assert(!Cleanup.exprNeedsCleanups() && "Unaccounted cleanups in function");
assert(MaybeODRUseExprs.empty() &&
"Leftover expressions for odr-use checking");
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 9 14:54:46 2016
@@ -712,7 +712,7 @@ ExprResult Sema::DefaultLvalueConversion
// balance that.
if (getLangOpts().ObjCAutoRefCount &&
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
nullptr, VK_RValue);
@@ -4573,15 +4573,15 @@ ExprResult Sema::BuildCXXDefaultArgExpr(
// bound temporaries; see the comment in PR5810.
// We don't need to do that with block decls, though, because
// blocks in default argument expression can never capture anything.
- if (isa<ExprWithCleanups>(Param->getInit())) {
+ if (auto Init = dyn_cast<ExprWithCleanups>(Param->getInit())) {
// Set the "needs cleanups" bit regardless of whether there are
// any explicit objects.
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(Init->cleanupsHaveSideEffects());
// Append all the objects to the cleanup list. Right now, this
// should always be a no-op, because blocks in default argument
// expressions should never be able to capture anything.
- assert(!cast<ExprWithCleanups>(Param->getInit())->getNumObjects() &&
+ assert(!Init->getNumObjects() &&
"default argument expression has capturing blocks?");
}
@@ -5596,7 +5596,7 @@ void Sema::maybeExtendBlockObject(ExprRe
E = ImplicitCastExpr::Create(Context, E.get()->getType(),
CK_ARCExtendBlockObject, E.get(),
/*base path*/ nullptr, VK_RValue);
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
}
/// Prepare a conversion of the given expression to an ObjC object
@@ -10382,8 +10382,8 @@ QualType Sema::CheckAddressOfOperand(Exp
if (sfinae)
return QualType();
// Materialize the temporary as an lvalue so that we can take its address.
- OrigOp = op = new (Context)
- MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
+ OrigOp = op =
+ CreateMaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
} else if (isa<ObjCSelectorExpr>(op)) {
return Context.getPointerType(op->getType());
} else if (lval == Expr::LV_MemberFunction) {
@@ -11596,7 +11596,8 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc
if (hasAnyUnrecoverableErrorsInThisFunction())
DiscardCleanupsInEvaluationContext();
- assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");
+ assert(!Cleanup.exprNeedsCleanups() &&
+ "cleanups within StmtExpr not correctly bound!");
PopExpressionEvaluationContext();
// FIXME: there are a variety of strange constraints to enforce here, for
@@ -12064,7 +12065,8 @@ ExprResult Sema::ActOnBlockStmtExpr(Sour
// Leave the expression-evaluation context.
if (hasAnyUnrecoverableErrorsInThisFunction())
DiscardCleanupsInEvaluationContext();
- assert(!ExprNeedsCleanups && "cleanups within block not correctly bound!");
+ assert(!Cleanup.exprNeedsCleanups() &&
+ "cleanups within block not correctly bound!");
PopExpressionEvaluationContext();
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
@@ -12155,7 +12157,7 @@ ExprResult Sema::ActOnBlockStmtExpr(Sour
if (Result->getBlockDecl()->hasCaptures()) {
// First, this expression has a new cleanup object.
ExprCleanupObjects.push_back(Result->getBlockDecl());
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
// It also gets a branch-protected scope if any of the captured
// variables needs destruction.
@@ -12792,10 +12794,9 @@ void
Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
Decl *LambdaContextDecl,
bool IsDecltype) {
- ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(),
- ExprNeedsCleanups, LambdaContextDecl,
- IsDecltype);
- ExprNeedsCleanups = false;
+ ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
+ LambdaContextDecl, IsDecltype);
+ Cleanup.reset();
if (!MaybeODRUseExprs.empty())
std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
}
@@ -12846,12 +12847,12 @@ void Sema::PopExpressionEvaluationContex
if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) {
ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects,
ExprCleanupObjects.end());
- ExprNeedsCleanups = Rec.ParentNeedsCleanups;
+ Cleanup = Rec.ParentCleanup;
CleanupVarDeclMarking();
std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs);
// Otherwise, merge the contexts together.
} else {
- ExprNeedsCleanups |= Rec.ParentNeedsCleanups;
+ Cleanup.mergeFrom(Rec.ParentCleanup);
MaybeODRUseExprs.insert(Rec.SavedMaybeODRUseExprs.begin(),
Rec.SavedMaybeODRUseExprs.end());
}
@@ -12870,7 +12871,7 @@ void Sema::DiscardCleanupsInEvaluationCo
ExprCleanupObjects.erase(
ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects,
ExprCleanupObjects.end());
- ExprNeedsCleanups = false;
+ Cleanup.reset();
MaybeODRUseExprs.clear();
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 9 14:54:46 2016
@@ -5551,7 +5551,7 @@ ExprResult Sema::MaybeBindToTemporary(Ex
if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
return E;
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
: CK_ARCReclaimReturnedObject);
@@ -5604,7 +5604,7 @@ ExprResult Sema::MaybeBindToTemporary(Ex
return E;
// We need a cleanup, but we don't need to remember the temporary.
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
}
CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
@@ -5631,14 +5631,16 @@ Expr *Sema::MaybeCreateExprWithCleanups(
unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
assert(ExprCleanupObjects.size() >= FirstCleanup);
- assert(ExprNeedsCleanups || ExprCleanupObjects.size() == FirstCleanup);
- if (!ExprNeedsCleanups)
+ assert(Cleanup.exprNeedsCleanups() ||
+ ExprCleanupObjects.size() == FirstCleanup);
+ if (!Cleanup.exprNeedsCleanups())
return SubExpr;
auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup,
ExprCleanupObjects.size() - FirstCleanup);
- Expr *E = ExprWithCleanups::Create(Context, SubExpr, Cleanups);
+ auto *E = ExprWithCleanups::Create(
+ Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups);
DiscardCleanupsInEvaluationContext();
return E;
@@ -5649,7 +5651,7 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(
CleanupVarDeclMarking();
- if (!ExprNeedsCleanups)
+ if (!Cleanup.exprNeedsCleanups())
return SubStmt;
// FIXME: In order to attach the temporaries, wrap the statement into
@@ -5755,7 +5757,7 @@ ExprResult Sema::ActOnDecltypeExpression
return ExprError();
// We need a cleanup, but we don't need to remember the temporary.
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
}
// Possibly strip off the top CXXBindTemporaryExpr.
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Thu Jun 9 14:54:46 2016
@@ -4067,7 +4067,7 @@ Sema::CheckObjCARCConversion(SourceRange
castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
CK_ARCConsumeObject, castExpr,
nullptr, VK_RValue);
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
return ACR_okay;
}
@@ -4310,7 +4310,7 @@ ExprResult Sema::BuildObjCBridgedCast(So
TSInfo, SubExpr);
if (MustConsume) {
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
nullptr, VK_RValue);
}
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jun 9 14:54:46 2016
@@ -4807,8 +4807,8 @@ static void checkIndirectCopyRestoreSour
// If isWeakAccess to true, there will be an implicit
// load which requires a cleanup.
if (S.getLangOpts().ObjCAutoRefCount && isWeakAccess)
- S.ExprNeedsCleanups = true;
-
+ S.Cleanup.setExprNeedsCleanups(true);
+
if (iik == IIK_okay) return;
S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)
@@ -6182,6 +6182,22 @@ static void CheckForNullPointerDereferen
}
}
+MaterializeTemporaryExpr *
+Sema::CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
+ bool BoundToLvalueReference) {
+ auto MTE = new (Context)
+ MaterializeTemporaryExpr(T, Temporary, BoundToLvalueReference);
+
+ // Order an ExprWithCleanups for lifetime marks.
+ //
+ // TODO: It'll be good to have a single place to check the access of the
+ // destructor and generate ExprWithCleanups for various uses. Currently these
+ // are done in both CreateMaterializeTemporaryExpr and MaybeBindToTemporary,
+ // but there may be a chance to merge them.
+ Cleanup.setExprNeedsCleanups(false);
+ return MTE;
+}
+
ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
@@ -6446,7 +6462,7 @@ InitializationSequence::Perform(Sema &S,
return ExprError();
// Materialize the temporary into memory.
- MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(
+ MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
Entity.getType().getNonReferenceType(), CurInit.get(),
Entity.getType()->isLValueReferenceType());
@@ -6466,7 +6482,7 @@ InitializationSequence::Perform(Sema &S,
MTE->getType()->isObjCLifetimeType()) ||
(MTE->getStorageDuration() == SD_Automatic &&
MTE->getType().isDestructedType()))
- S.ExprNeedsCleanups = true;
+ S.Cleanup.setExprNeedsCleanups(true);
CurInit = MTE;
break;
@@ -6858,9 +6874,9 @@ InitializationSequence::Perform(Sema &S,
<< CurInit.get()->getSourceRange();
// Materialize the temporary into memory.
- MaterializeTemporaryExpr *MTE = new (S.Context)
- MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(),
- /*BoundToLvalueReference=*/false);
+ MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
+ CurInit.get()->getType(), CurInit.get(),
+ /*BoundToLvalueReference=*/false);
// Maybe lifetime-extend the array temporary's subobjects to match the
// entity's lifetime.
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu Jun 9 14:54:46 2016
@@ -1500,7 +1500,7 @@ ExprResult Sema::BuildLambdaExpr(SourceL
SourceRange IntroducerRange;
bool ExplicitParams;
bool ExplicitResultType;
- bool LambdaExprNeedsCleanups;
+ CleanupInfo LambdaCleanup;
bool ContainsUnexpandedParameterPack;
SmallVector<VarDecl *, 4> ArrayIndexVars;
SmallVector<unsigned, 4> ArrayIndexStarts;
@@ -1510,7 +1510,7 @@ ExprResult Sema::BuildLambdaExpr(SourceL
IntroducerRange = LSI->IntroducerRange;
ExplicitParams = LSI->ExplicitParams;
ExplicitResultType = !LSI->HasImplicitReturnType;
- LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
+ LambdaCleanup = LSI->Cleanup;
ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
CallOperator->setLexicalDeclContext(Class);
@@ -1591,9 +1591,8 @@ ExprResult Sema::BuildLambdaExpr(SourceL
CheckCompletedCXXClass(Class);
}
- if (LambdaExprNeedsCleanups)
- ExprNeedsCleanups = true;
-
+ Cleanup.mergeFrom(LambdaCleanup);
+
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
CaptureDefault, CaptureDefaultLoc,
Captures,
@@ -1714,7 +1713,7 @@ ExprResult Sema::BuildBlockForLambdaConv
// Create the block literal expression.
Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType());
ExprCleanupObjects.push_back(Block);
- ExprNeedsCleanups = true;
+ Cleanup.setExprNeedsCleanups(true);
return BuildBlock;
}
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jun 9 14:54:46 2016
@@ -3801,6 +3801,10 @@ bool OpenMPIterationSpaceChecker::CheckI
}
return true;
}
+ if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
+ if (!ExprTemp->cleanupsHaveSideEffects())
+ S = ExprTemp->getSubExpr();
+
InitSrcRange = S->getSourceRange();
if (Expr *E = dyn_cast<Expr>(S))
S = E->IgnoreParens();
@@ -3988,6 +3992,10 @@ bool OpenMPIterationSpaceChecker::CheckI
SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
return true;
}
+ if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
+ if (!ExprTemp->cleanupsHaveSideEffects())
+ S = ExprTemp->getSubExpr();
+
IncrementSrcRange = S->getSourceRange();
S = S->IgnoreParens();
if (auto UO = dyn_cast<UnaryOperator>(S)) {
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jun 9 14:54:46 2016
@@ -1518,6 +1518,10 @@ namespace {
// variables Increment and DRE.
bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
DeclRefExpr *&DRE) {
+ if (auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))
+ if (!Cleanups->cleanupsHaveSideEffects())
+ Statement = Cleanups->getSubExpr();
+
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
switch (UO->getOpcode()) {
default: return false;
@@ -2472,6 +2476,10 @@ static void DiagnoseForRangeReferenceVar
QualType VariableType = VD->getType();
+ if (auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))
+ if (!Cleanups->cleanupsHaveSideEffects())
+ InitExpr = Cleanups->getSubExpr();
+
const MaterializeTemporaryExpr *MTE =
dyn_cast<MaterializeTemporaryExpr>(InitExpr);
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Jun 9 14:54:46 2016
@@ -1448,6 +1448,7 @@ void ASTStmtReader::VisitExprWithCleanup
E->getTrailingObjects<BlockDecl *>()[i] =
ReadDeclAs<BlockDecl>(Record, Idx);
+ E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record[Idx++];
E->SubExpr = Reader.ReadSubExpr();
}
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Jun 9 14:54:46 2016
@@ -1430,7 +1430,8 @@ void ASTStmtWriter::VisitExprWithCleanup
Record.push_back(E->getNumObjects());
for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
Record.AddDeclRef(E->getObject(i));
-
+
+ Record.push_back(E->cleanupsHaveSideEffects());
Record.AddStmt(E->getSubExpr());
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
}
Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp?rev=272296&r1=272295&r2=272296&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Thu Jun 9 14:54:46 2016
@@ -999,8 +999,8 @@ TEST(ExprWithCleanups, MatchesExprWithCl
EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
"const Foo f = Foo();",
varDecl(hasInitializer(exprWithCleanups()))));
- EXPECT_FALSE(matches("struct Foo { };"
- "const Foo f = Foo();",
+ EXPECT_FALSE(matches("struct Foo { }; Foo a;"
+ "const Foo f = a;",
varDecl(hasInitializer(exprWithCleanups()))));
}
More information about the cfe-commits
mailing list