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