summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp7
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp1
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp37
-rw-r--r--clang/lib/Sema/SemaInit.cpp14
-rw-r--r--clang/lib/Sema/SemaLambda.cpp10
5 files changed, 26 insertions, 43 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index b9606876e43..f284baf2b66 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3255,11 +3255,8 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case LambdaExprClass: {
const LambdaExpr *LE = cast<LambdaExpr>(this);
- for (LambdaExpr::capture_iterator I = LE->capture_begin(),
- E = LE->capture_end(); I != E; ++I)
- if (I->getCaptureKind() == LCK_ByCopy)
- // FIXME: Only has a side-effect if the variable is volatile or if
- // the copy would invoke a non-trivial copy constructor.
+ for (Expr *E : LE->capture_inits())
+ if (E->HasSideEffects(Ctx, IncludePossibleEffects))
return true;
return false;
}
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 393a4aa7870..ae6653ec483 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -2252,7 +2252,6 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
}
void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) {
- RunCleanupsScope Scope(*this);
LValue SlotLV = MakeAddrLValue(Slot.getAddress(), E->getType());
CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index dd5dfaacf24..eb1dd8975d1 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7764,41 +7764,24 @@ Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl,
ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
bool DiscardedValue,
- bool IsConstexpr,
- bool IsLambdaInitCaptureInitializer) {
+ bool IsConstexpr) {
ExprResult FullExpr = FE;
if (!FullExpr.get())
return ExprError();
- // If we are an init-expression in a lambdas init-capture, we should not
- // diagnose an unexpanded pack now (will be diagnosed once lambda-expr
- // containing full-expression is done).
- // template<class ... Ts> void test(Ts ... t) {
- // test([&a(t)]() { <-- (t) is an init-expr that shouldn't be diagnosed now.
- // return a;
- // }() ...);
- // }
- // FIXME: This is a hack. It would be better if we pushed the lambda scope
- // when we parse the lambda introducer, and teach capturing (but not
- // unexpanded pack detection) to walk over LambdaScopeInfos which don't have a
- // corresponding class yet (that is, have LambdaScopeInfo either represent a
- // lambda where we've entered the introducer but not the body, or represent a
- // lambda where we've entered the body, depending on where the
- // parser/instantiation has got to).
- if (!IsLambdaInitCaptureInitializer &&
- DiagnoseUnexpandedParameterPack(FullExpr.get()))
+ if (DiagnoseUnexpandedParameterPack(FullExpr.get()))
return ExprError();
- // Top-level expressions default to 'id' when we're in a debugger.
- if (DiscardedValue && getLangOpts().DebuggerCastResultToId &&
- FullExpr.get()->getType() == Context.UnknownAnyTy) {
- FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
- if (FullExpr.isInvalid())
- return ExprError();
- }
-
if (DiscardedValue) {
+ // Top-level expressions default to 'id' when we're in a debugger.
+ if (getLangOpts().DebuggerCastResultToId &&
+ FullExpr.get()->getType() == Context.UnknownAnyTy) {
+ FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
+ if (FullExpr.isInvalid())
+ return ExprError();
+ }
+
FullExpr = CheckPlaceholderExpr(FullExpr.get());
if (FullExpr.isInvalid())
return ExprError();
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 958dd66612c..71f3c4e34b5 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6786,6 +6786,20 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
return;
}
+ // The lifetime of an init-capture is that of the closure object constructed
+ // by a lambda-expression.
+ if (auto *LE = dyn_cast<LambdaExpr>(Init)) {
+ for (Expr *E : LE->capture_inits()) {
+ if (!E)
+ continue;
+ if (E->isGLValue())
+ visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding,
+ Visit);
+ else
+ visitLocalsRetainedByInitializer(Path, E, Visit, true);
+ }
+ }
+
if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init))
return visitLifetimeBoundArguments(Path, Init, Visit);
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 8000cb4fbfd..803b253e458 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -775,16 +775,6 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
if (Result.isInvalid())
return QualType();
- Init = Result.getAs<Expr>();
-
- // The init-capture initialization is a full-expression that must be
- // processed as one before we enter the declcontext of the lambda's
- // call-operator.
- Result = ActOnFinishFullExpr(Init, Loc, /*DiscardedValue*/ false,
- /*IsConstexpr*/ false,
- /*IsLambdaInitCaptureInitializer*/ true);
- if (Result.isInvalid())
- return QualType();
Init = Result.getAs<Expr>();
return DeducedType;
OpenPOWER on IntegriCloud