I think this broke the build on windows: http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/7421/steps/build/logs/stdio
Cheers, Rafael On 21 June 2016 at 16:29, Tim Shen via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: timshen > Date: Tue Jun 21 15:29:17 2016 > New Revision: 273312 > > URL: http://llvm.org/viewvc/llvm-project?rev=273312&view=rev > Log: > Re-commit "[Temporary] Add an ExprWithCleanups for each C++ > MaterializeTemporaryExpr." > > Since D21243 fixes relative clang-tidy tests. > > This reverts commit a71d9fbd41e99def9159af2b01ef6509394eaeed. > > 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/ExprCXX.h (original) > +++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Jun 21 15:29:17 2016 > @@ -2872,7 +2872,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; > @@ -2882,6 +2883,7 @@ public: > unsigned numObjects); > > static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, > + bool CleanupsHaveSideEffects, > ArrayRef<CleanupObject> objects); > > ArrayRef<CleanupObject> getObjects() const { > @@ -2898,6 +2900,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/Stmt.h (original) > +++ cfe/trunk/include/clang/AST/Stmt.h Tue Jun 21 15:29:17 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=273312&view=auto > ============================================================================== > --- cfe/trunk/include/clang/Sema/CleanupInfo.h (added) > +++ cfe/trunk/include/clang/Sema/CleanupInfo.h Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/ScopeInfo.h (original) > +++ cfe/trunk/include/clang/Sema/ScopeInfo.h Tue Jun 21 15:29:17 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" > @@ -688,7 +689,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; > @@ -736,7 +737,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 21 15:29:17 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() { } > @@ -4883,6 +4883,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Expr.cpp (original) > +++ cfe/trunk/lib/AST/Expr.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ExprCXX.cpp (original) > +++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Jun 21 15:29:17 2016 > @@ -1023,6 +1023,7 @@ bool LambdaExpr::isMutable() const { > } > > ExprWithCleanups::ExprWithCleanups(Expr *subexpr, > + bool CleanupsHaveSideEffects, > ArrayRef<CleanupObject> objects) > : Expr(ExprWithCleanupsClass, subexpr->getType(), > subexpr->getValueKind(), subexpr->getObjectKind(), > @@ -1030,16 +1031,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Analysis/Consumed.cpp (original) > +++ cfe/trunk/lib/Analysis/Consumed.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/Sema.cpp (original) > +++ cfe/trunk/lib/Sema/Sema.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCast.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCast.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jun 21 15:29:17 2016 > @@ -11647,7 +11647,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 21 15:29:17 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); > @@ -4580,15 +4580,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?"); > } > > @@ -5603,7 +5603,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 > @@ -10389,8 +10389,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) { > @@ -11603,7 +11603,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 > @@ -12071,7 +12072,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()); > @@ -12162,7 +12164,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. > @@ -12799,10 +12801,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); > } > @@ -12853,12 +12854,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()); > } > @@ -12877,7 +12878,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jun 21 15:29:17 2016 > @@ -5644,7 +5644,7 @@ ExprResult Sema::MaybeBindToTemporary(Ex > if (!ReturnsRetained && > E->getType()->isObjCARCImplicitlyUnretainedType()) > return E; > > - ExprNeedsCleanups = true; > + Cleanup.setExprNeedsCleanups(true); > > CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject > : CK_ARCReclaimReturnedObject); > @@ -5697,7 +5697,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); > @@ -5724,14 +5724,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; > @@ -5742,7 +5744,7 @@ Stmt *Sema::MaybeCreateStmtWithCleanups( > > CleanupVarDeclMarking(); > > - if (!ExprNeedsCleanups) > + if (!Cleanup.exprNeedsCleanups()) > return SubStmt; > > // FIXME: In order to attach the temporaries, wrap the statement into > @@ -5848,7 +5850,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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaInit.cpp (original) > +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) > +++ cfe/trunk/lib/Sema/SemaLambda.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) > +++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jun 21 15:29:17 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=273312&r1=273311&r2=273312&view=diff > ============================================================================== > --- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (original) > +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Tue Jun 21 > 15:29:17 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())))); > } > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits