|
@@ -6553,11 +6553,13 @@ static bool pathContainsInit(IndirectLocalPath &Path) {
|
|
|
|
|
|
static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
Expr *Init, LocalVisitor Visit,
|
|
Expr *Init, LocalVisitor Visit,
|
|
- bool RevisitSubinits);
|
|
|
|
|
|
+ bool RevisitSubinits,
|
|
|
|
+ bool EnableLifetimeWarnings);
|
|
|
|
|
|
static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
Expr *Init, ReferenceKind RK,
|
|
Expr *Init, ReferenceKind RK,
|
|
- LocalVisitor Visit);
|
|
|
|
|
|
+ LocalVisitor Visit,
|
|
|
|
+ bool EnableLifetimeWarnings);
|
|
|
|
|
|
template <typename T> static bool isRecordWithAttr(QualType Type) {
|
|
template <typename T> static bool isRecordWithAttr(QualType Type) {
|
|
if (auto *RD = Type->getAsCXXRecordDecl())
|
|
if (auto *RD = Type->getAsCXXRecordDecl())
|
|
@@ -6646,9 +6648,9 @@ static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call,
|
|
Path.push_back({IndirectLocalPathEntry::GslPointerInit, Arg, D});
|
|
Path.push_back({IndirectLocalPathEntry::GslPointerInit, Arg, D});
|
|
if (Arg->isGLValue())
|
|
if (Arg->isGLValue())
|
|
visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
|
|
visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
|
|
- Visit);
|
|
|
|
|
|
+ Visit, true);
|
|
else
|
|
else
|
|
- visitLocalsRetainedByInitializer(Path, Arg, Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, Arg, Visit, true, true);
|
|
Path.pop_back();
|
|
Path.pop_back();
|
|
};
|
|
};
|
|
|
|
|
|
@@ -6723,9 +6725,9 @@ static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
|
|
Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D});
|
|
Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D});
|
|
if (Arg->isGLValue())
|
|
if (Arg->isGLValue())
|
|
visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
|
|
visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding,
|
|
- Visit);
|
|
|
|
|
|
+ Visit, false);
|
|
else
|
|
else
|
|
- visitLocalsRetainedByInitializer(Path, Arg, Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, Arg, Visit, true, false);
|
|
Path.pop_back();
|
|
Path.pop_back();
|
|
};
|
|
};
|
|
|
|
|
|
@@ -6744,7 +6746,8 @@ static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
|
|
/// glvalue expression \c Init.
|
|
/// glvalue expression \c Init.
|
|
static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
Expr *Init, ReferenceKind RK,
|
|
Expr *Init, ReferenceKind RK,
|
|
- LocalVisitor Visit) {
|
|
|
|
|
|
+ LocalVisitor Visit,
|
|
|
|
+ bool EnableLifetimeWarnings) {
|
|
RevertToOldSizeRAII RAII(Path);
|
|
RevertToOldSizeRAII RAII(Path);
|
|
|
|
|
|
// Walk past any constructs which we can lifetime-extend across.
|
|
// Walk past any constructs which we can lifetime-extend across.
|
|
@@ -6781,7 +6784,8 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
else
|
|
else
|
|
// We can't lifetime extend through this but we might still find some
|
|
// We can't lifetime extend through this but we might still find some
|
|
// retained temporaries.
|
|
// retained temporaries.
|
|
- return visitLocalsRetainedByInitializer(Path, Init, Visit, true);
|
|
|
|
|
|
+ return visitLocalsRetainedByInitializer(Path, Init, Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
|
|
|
|
// Step into CXXDefaultInitExprs so we can diagnose cases where a
|
|
// Step into CXXDefaultInitExprs so we can diagnose cases where a
|
|
@@ -6796,11 +6800,12 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) {
|
|
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) {
|
|
if (Visit(Path, Local(MTE), RK))
|
|
if (Visit(Path, Local(MTE), RK))
|
|
visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(), Visit,
|
|
visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(), Visit,
|
|
- true);
|
|
|
|
|
|
+ true, EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
|
|
|
|
if (isa<CallExpr>(Init)) {
|
|
if (isa<CallExpr>(Init)) {
|
|
- handleGslAnnotatedTypes(Path, Init, Visit);
|
|
|
|
|
|
+ if (EnableLifetimeWarnings)
|
|
|
|
+ handleGslAnnotatedTypes(Path, Init, Visit);
|
|
return visitLifetimeBoundArguments(Path, Init, Visit);
|
|
return visitLifetimeBoundArguments(Path, Init, Visit);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6821,7 +6826,8 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
} else if (VD->getInit() && !isVarOnPath(Path, VD)) {
|
|
} else if (VD->getInit() && !isVarOnPath(Path, VD)) {
|
|
Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
|
|
Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
|
|
visitLocalsRetainedByReferenceBinding(Path, VD->getInit(),
|
|
visitLocalsRetainedByReferenceBinding(Path, VD->getInit(),
|
|
- RK_ReferenceBinding, Visit);
|
|
|
|
|
|
+ RK_ReferenceBinding, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -6833,13 +6839,15 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
// handling all sorts of rvalues passed to a unary operator.
|
|
// handling all sorts of rvalues passed to a unary operator.
|
|
const UnaryOperator *U = cast<UnaryOperator>(Init);
|
|
const UnaryOperator *U = cast<UnaryOperator>(Init);
|
|
if (U->getOpcode() == UO_Deref)
|
|
if (U->getOpcode() == UO_Deref)
|
|
- visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
case Stmt::OMPArraySectionExprClass: {
|
|
case Stmt::OMPArraySectionExprClass: {
|
|
- visitLocalsRetainedByInitializer(
|
|
|
|
- Path, cast<OMPArraySectionExpr>(Init)->getBase(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path,
|
|
|
|
+ cast<OMPArraySectionExpr>(Init)->getBase(),
|
|
|
|
+ Visit, true, EnableLifetimeWarnings);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6847,9 +6855,11 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
case Stmt::BinaryConditionalOperatorClass: {
|
|
case Stmt::BinaryConditionalOperatorClass: {
|
|
auto *C = cast<AbstractConditionalOperator>(Init);
|
|
auto *C = cast<AbstractConditionalOperator>(Init);
|
|
if (!C->getTrueExpr()->getType()->isVoidType())
|
|
if (!C->getTrueExpr()->getType()->isVoidType())
|
|
- visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit);
|
|
|
|
|
|
+ visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
if (!C->getFalseExpr()->getType()->isVoidType())
|
|
if (!C->getFalseExpr()->getType()->isVoidType())
|
|
- visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit);
|
|
|
|
|
|
+ visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6864,7 +6874,8 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
|
|
/// the prvalue expression \c Init.
|
|
/// the prvalue expression \c Init.
|
|
static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
Expr *Init, LocalVisitor Visit,
|
|
Expr *Init, LocalVisitor Visit,
|
|
- bool RevisitSubinits) {
|
|
|
|
|
|
+ bool RevisitSubinits,
|
|
|
|
+ bool EnableLifetimeWarnings) {
|
|
RevertToOldSizeRAII RAII(Path);
|
|
RevertToOldSizeRAII RAII(Path);
|
|
|
|
|
|
Expr *Old;
|
|
Expr *Old;
|
|
@@ -6904,15 +6915,17 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
if (VD && VD->getType().isConstQualified() && VD->getInit() &&
|
|
if (VD && VD->getType().isConstQualified() && VD->getInit() &&
|
|
!isVarOnPath(Path, VD)) {
|
|
!isVarOnPath(Path, VD)) {
|
|
Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
|
|
Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
|
|
- visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
} else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
|
|
} else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
|
|
if (MTE->getType().isConstQualified())
|
|
if (MTE->getType().isConstQualified())
|
|
visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(),
|
|
visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(),
|
|
- Visit, true);
|
|
|
|
|
|
+ Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
- });
|
|
|
|
|
|
+ }, EnableLifetimeWarnings);
|
|
|
|
|
|
// We assume that objects can be retained by pointers cast to integers,
|
|
// We assume that objects can be retained by pointers cast to integers,
|
|
// but not if the integer is cast to floating-point type or to _Complex.
|
|
// but not if the integer is cast to floating-point type or to _Complex.
|
|
@@ -6942,7 +6955,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
// lvalue.
|
|
// lvalue.
|
|
Path.push_back({IndirectLocalPathEntry::AddressOf, CE});
|
|
Path.push_back({IndirectLocalPathEntry::AddressOf, CE});
|
|
return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(),
|
|
return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(),
|
|
- RK_ReferenceBinding, Visit);
|
|
|
|
|
|
+ RK_ReferenceBinding, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
|
|
|
|
default:
|
|
default:
|
|
return;
|
|
return;
|
|
@@ -6957,7 +6971,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
// lifetime of the array exactly like binding a reference to a temporary.
|
|
// lifetime of the array exactly like binding a reference to a temporary.
|
|
if (auto *ILE = dyn_cast<CXXStdInitializerListExpr>(Init))
|
|
if (auto *ILE = dyn_cast<CXXStdInitializerListExpr>(Init))
|
|
return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(),
|
|
return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(),
|
|
- RK_StdInitializerList, Visit);
|
|
|
|
|
|
+ RK_StdInitializerList, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
|
|
|
|
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
|
|
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
|
|
// We already visited the elements of this initializer list while
|
|
// We already visited the elements of this initializer list while
|
|
@@ -6968,12 +6983,14 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
|
|
|
|
if (ILE->isTransparent())
|
|
if (ILE->isTransparent())
|
|
return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit,
|
|
return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit,
|
|
- RevisitSubinits);
|
|
|
|
|
|
+ RevisitSubinits,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
|
|
|
|
if (ILE->getType()->isArrayType()) {
|
|
if (ILE->getType()->isArrayType()) {
|
|
for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
|
|
for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
|
|
visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit,
|
|
visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit,
|
|
- RevisitSubinits);
|
|
|
|
|
|
+ RevisitSubinits,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6986,12 +7003,14 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
|
|
if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
|
|
ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
|
|
ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
|
|
visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0),
|
|
visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0),
|
|
- RK_ReferenceBinding, Visit);
|
|
|
|
|
|
+ RK_ReferenceBinding, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
else {
|
|
else {
|
|
unsigned Index = 0;
|
|
unsigned Index = 0;
|
|
for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index)
|
|
for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index)
|
|
visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit,
|
|
visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit,
|
|
- RevisitSubinits);
|
|
|
|
|
|
+ RevisitSubinits,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
for (const auto *I : RD->fields()) {
|
|
for (const auto *I : RD->fields()) {
|
|
if (Index >= ILE->getNumInits())
|
|
if (Index >= ILE->getNumInits())
|
|
break;
|
|
break;
|
|
@@ -7000,13 +7019,15 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
Expr *SubInit = ILE->getInit(Index);
|
|
Expr *SubInit = ILE->getInit(Index);
|
|
if (I->getType()->isReferenceType())
|
|
if (I->getType()->isReferenceType())
|
|
visitLocalsRetainedByReferenceBinding(Path, SubInit,
|
|
visitLocalsRetainedByReferenceBinding(Path, SubInit,
|
|
- RK_ReferenceBinding, Visit);
|
|
|
|
|
|
+ RK_ReferenceBinding, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
else
|
|
else
|
|
// This might be either aggregate-initialization of a member or
|
|
// This might be either aggregate-initialization of a member or
|
|
// initialization of a std::initializer_list object. Regardless,
|
|
// initialization of a std::initializer_list object. Regardless,
|
|
// we should recursively lifetime-extend that initializer.
|
|
// we should recursively lifetime-extend that initializer.
|
|
visitLocalsRetainedByInitializer(Path, SubInit, Visit,
|
|
visitLocalsRetainedByInitializer(Path, SubInit, Visit,
|
|
- RevisitSubinits);
|
|
|
|
|
|
+ RevisitSubinits,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
++Index;
|
|
++Index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -7022,14 +7043,16 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
continue;
|
|
continue;
|
|
if (E->isGLValue())
|
|
if (E->isGLValue())
|
|
visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding,
|
|
visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding,
|
|
- Visit);
|
|
|
|
|
|
+ Visit, EnableLifetimeWarnings);
|
|
else
|
|
else
|
|
- visitLocalsRetainedByInitializer(Path, E, Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, E, Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) {
|
|
if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) {
|
|
- handleGslAnnotatedTypes(Path, Init, Visit);
|
|
|
|
|
|
+ if (EnableLifetimeWarnings)
|
|
|
|
+ handleGslAnnotatedTypes(Path, Init, Visit);
|
|
return visitLifetimeBoundArguments(Path, Init, Visit);
|
|
return visitLifetimeBoundArguments(Path, Init, Visit);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -7047,7 +7070,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
|
|
|
|
Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
|
|
Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
|
|
visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(),
|
|
visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(),
|
|
- RK_ReferenceBinding, Visit);
|
|
|
|
|
|
+ RK_ReferenceBinding, Visit,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -7060,9 +7084,11 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
break;
|
|
break;
|
|
|
|
|
|
if (BO->getLHS()->getType()->isPointerType())
|
|
if (BO->getLHS()->getType()->isPointerType())
|
|
- visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
else if (BO->getRHS()->getType()->isPointerType())
|
|
else if (BO->getRHS()->getType()->isPointerType())
|
|
- visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -7072,9 +7098,11 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
|
|
// In C++, we can have a throw-expression operand, which has 'void' type
|
|
// In C++, we can have a throw-expression operand, which has 'void' type
|
|
// and isn't interesting from a lifetime perspective.
|
|
// and isn't interesting from a lifetime perspective.
|
|
if (!C->getTrueExpr()->getType()->isVoidType())
|
|
if (!C->getTrueExpr()->getType()->isVoidType())
|
|
- visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
if (!C->getFalseExpr()->getType()->isVoidType())
|
|
if (!C->getFalseExpr()->getType()->isVoidType())
|
|
- visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -7381,12 +7409,16 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity,
|
|
return false;
|
|
return false;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ bool EnableLifetimeWarnings = !getDiagnostics().isIgnored(
|
|
|
|
+ diag::warn_dangling_lifetime_pointer, SourceLocation());
|
|
llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
|
|
llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
|
|
if (Init->isGLValue())
|
|
if (Init->isGLValue())
|
|
visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
|
|
visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
|
|
- TemporaryVisitor);
|
|
|
|
|
|
+ TemporaryVisitor,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
else
|
|
else
|
|
- visitLocalsRetainedByInitializer(Path, Init, TemporaryVisitor, false);
|
|
|
|
|
|
+ visitLocalsRetainedByInitializer(Path, Init, TemporaryVisitor, false,
|
|
|
|
+ EnableLifetimeWarnings);
|
|
}
|
|
}
|
|
|
|
|
|
static void DiagnoseNarrowingInInitList(Sema &S,
|
|
static void DiagnoseNarrowingInInitList(Sema &S,
|