r273312 - Re-commit "[Temporary] Add an ExprWithCleanups for each C++ MaterializeTemporaryExpr."
Rafael EspĂndola via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 21 14:33:56 PDT 2016
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 at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list