Author: xazax Date: Fri Aug 23 15:21:33 2019 New Revision: 369817 URL: http://llvm.org/viewvc/llvm-project?rev=369817&view=rev Log: [LifetimeAnalysis] Make it possible to disable the new warnings
Added: cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaInit.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=369817&r1=369816&r2=369817&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Aug 23 15:21:33 2019 @@ -289,9 +289,11 @@ def OverloadedShiftOpParentheses: DiagGr def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DanglingInitializerList : DiagGroup<"dangling-initializer-list">; +def DanglingGsl : DiagGroup<"dangling-gsl">; def ReturnStackAddress : DiagGroup<"return-stack-address">; def Dangling : DiagGroup<"dangling", [DanglingField, DanglingInitializerList, + DanglingGsl, ReturnStackAddress]>; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; def ExpansionToDefined : DiagGroup<"expansion-to-defined">; Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=369817&r1=369816&r2=369817&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Aug 23 15:21:33 2019 @@ -8121,7 +8121,7 @@ def warn_dangling_member : Warning< def warn_dangling_lifetime_pointer_member : Warning< "initializing pointer member %0 to point to a temporary object " "whose lifetime is shorter than the lifetime of the constructed object">, - InGroup<DanglingField>; + InGroup<DanglingGsl>; def note_lifetime_extending_member_declared_here : Note< "%select{%select{reference|'std::initializer_list'}0 member|" "member with %select{reference|'std::initializer_list'}0 subobject}1 " @@ -8143,7 +8143,7 @@ def warn_new_dangling_reference : Warnin def warn_dangling_lifetime_pointer : Warning< "object backing the pointer " "will be destroyed at the end of the full-expression">, - InGroup<Dangling>; + InGroup<DanglingGsl>; def warn_new_dangling_initializer_list : Warning< "array backing " "%select{initializer list subobject of the allocated object|" Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=369817&r1=369816&r2=369817&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Aug 23 15:21:33 2019 @@ -6553,11 +6553,13 @@ static bool pathContainsInit(IndirectLoc static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *Init, LocalVisitor Visit, - bool RevisitSubinits); + bool RevisitSubinits, + bool EnableLifetimeWarnings); static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, Expr *Init, ReferenceKind RK, - LocalVisitor Visit); + LocalVisitor Visit, + bool EnableLifetimeWarnings); template <typename T> static bool isRecordWithAttr(QualType Type) { if (auto *RD = Type->getAsCXXRecordDecl()) @@ -6646,9 +6648,9 @@ static void handleGslAnnotatedTypes(Indi Path.push_back({IndirectLocalPathEntry::GslPointerInit, Arg, D}); if (Arg->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding, - Visit); + Visit, true); else - visitLocalsRetainedByInitializer(Path, Arg, Visit, true); + visitLocalsRetainedByInitializer(Path, Arg, Visit, true, true); Path.pop_back(); }; @@ -6723,9 +6725,9 @@ static void visitLifetimeBoundArguments( Path.push_back({IndirectLocalPathEntry::LifetimeBoundCall, Arg, D}); if (Arg->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Arg, RK_ReferenceBinding, - Visit); + Visit, false); else - visitLocalsRetainedByInitializer(Path, Arg, Visit, true); + visitLocalsRetainedByInitializer(Path, Arg, Visit, true, false); Path.pop_back(); }; @@ -6744,7 +6746,8 @@ static void visitLifetimeBoundArguments( /// glvalue expression \c Init. static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, Expr *Init, ReferenceKind RK, - LocalVisitor Visit) { + LocalVisitor Visit, + bool EnableLifetimeWarnings) { RevertToOldSizeRAII RAII(Path); // Walk past any constructs which we can lifetime-extend across. @@ -6781,7 +6784,8 @@ static void visitLocalsRetainedByReferen else // We can't lifetime extend through this but we might still find some // 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 @@ -6796,11 +6800,12 @@ static void visitLocalsRetainedByReferen if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) { if (Visit(Path, Local(MTE), RK)) visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(), Visit, - true); + true, EnableLifetimeWarnings); } if (isa<CallExpr>(Init)) { - handleGslAnnotatedTypes(Path, Init, Visit); + if (EnableLifetimeWarnings) + handleGslAnnotatedTypes(Path, Init, Visit); return visitLifetimeBoundArguments(Path, Init, Visit); } @@ -6821,7 +6826,8 @@ static void visitLocalsRetainedByReferen } else if (VD->getInit() && !isVarOnPath(Path, VD)) { Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD}); visitLocalsRetainedByReferenceBinding(Path, VD->getInit(), - RK_ReferenceBinding, Visit); + RK_ReferenceBinding, Visit, + EnableLifetimeWarnings); } } break; @@ -6833,13 +6839,15 @@ static void visitLocalsRetainedByReferen // handling all sorts of rvalues passed to a unary operator. const UnaryOperator *U = cast<UnaryOperator>(Init); if (U->getOpcode() == UO_Deref) - visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true); + visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true, + EnableLifetimeWarnings); break; } case Stmt::OMPArraySectionExprClass: { - visitLocalsRetainedByInitializer( - Path, cast<OMPArraySectionExpr>(Init)->getBase(), Visit, true); + visitLocalsRetainedByInitializer(Path, + cast<OMPArraySectionExpr>(Init)->getBase(), + Visit, true, EnableLifetimeWarnings); break; } @@ -6847,9 +6855,11 @@ static void visitLocalsRetainedByReferen case Stmt::BinaryConditionalOperatorClass: { auto *C = cast<AbstractConditionalOperator>(Init); if (!C->getTrueExpr()->getType()->isVoidType()) - visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit); + visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit, + EnableLifetimeWarnings); if (!C->getFalseExpr()->getType()->isVoidType()) - visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit); + visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit, + EnableLifetimeWarnings); break; } @@ -6864,7 +6874,8 @@ static void visitLocalsRetainedByReferen /// the prvalue expression \c Init. static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Expr *Init, LocalVisitor Visit, - bool RevisitSubinits) { + bool RevisitSubinits, + bool EnableLifetimeWarnings) { RevertToOldSizeRAII RAII(Path); Expr *Old; @@ -6904,15 +6915,17 @@ static void visitLocalsRetainedByInitial if (VD && VD->getType().isConstQualified() && VD->getInit() && !isVarOnPath(Path, 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)) { if (MTE->getType().isConstQualified()) visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(), - Visit, true); + Visit, true, + EnableLifetimeWarnings); } return false; - }); + }, EnableLifetimeWarnings); // 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. @@ -6942,7 +6955,8 @@ static void visitLocalsRetainedByInitial // lvalue. Path.push_back({IndirectLocalPathEntry::AddressOf, CE}); return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(), - RK_ReferenceBinding, Visit); + RK_ReferenceBinding, Visit, + EnableLifetimeWarnings); default: return; @@ -6957,7 +6971,8 @@ static void visitLocalsRetainedByInitial // lifetime of the array exactly like binding a reference to a temporary. if (auto *ILE = dyn_cast<CXXStdInitializerListExpr>(Init)) return visitLocalsRetainedByReferenceBinding(Path, ILE->getSubExpr(), - RK_StdInitializerList, Visit); + RK_StdInitializerList, Visit, + EnableLifetimeWarnings); if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) { // We already visited the elements of this initializer list while @@ -6968,12 +6983,14 @@ static void visitLocalsRetainedByInitial if (ILE->isTransparent()) return visitLocalsRetainedByInitializer(Path, ILE->getInit(0), Visit, - RevisitSubinits); + RevisitSubinits, + EnableLifetimeWarnings); if (ILE->getType()->isArrayType()) { for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I) visitLocalsRetainedByInitializer(Path, ILE->getInit(I), Visit, - RevisitSubinits); + RevisitSubinits, + EnableLifetimeWarnings); return; } @@ -6986,12 +7003,14 @@ static void visitLocalsRetainedByInitial if (RD->isUnion() && ILE->getInitializedFieldInUnion() && ILE->getInitializedFieldInUnion()->getType()->isReferenceType()) visitLocalsRetainedByReferenceBinding(Path, ILE->getInit(0), - RK_ReferenceBinding, Visit); + RK_ReferenceBinding, Visit, + EnableLifetimeWarnings); else { unsigned Index = 0; for (; Index < RD->getNumBases() && Index < ILE->getNumInits(); ++Index) visitLocalsRetainedByInitializer(Path, ILE->getInit(Index), Visit, - RevisitSubinits); + RevisitSubinits, + EnableLifetimeWarnings); for (const auto *I : RD->fields()) { if (Index >= ILE->getNumInits()) break; @@ -7000,13 +7019,15 @@ static void visitLocalsRetainedByInitial Expr *SubInit = ILE->getInit(Index); if (I->getType()->isReferenceType()) visitLocalsRetainedByReferenceBinding(Path, SubInit, - RK_ReferenceBinding, Visit); + RK_ReferenceBinding, Visit, + EnableLifetimeWarnings); else // This might be either aggregate-initialization of a member or // initialization of a std::initializer_list object. Regardless, // we should recursively lifetime-extend that initializer. visitLocalsRetainedByInitializer(Path, SubInit, Visit, - RevisitSubinits); + RevisitSubinits, + EnableLifetimeWarnings); ++Index; } } @@ -7022,14 +7043,16 @@ static void visitLocalsRetainedByInitial continue; if (E->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding, - Visit); + Visit, EnableLifetimeWarnings); else - visitLocalsRetainedByInitializer(Path, E, Visit, true); + visitLocalsRetainedByInitializer(Path, E, Visit, true, + EnableLifetimeWarnings); } } if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) { - handleGslAnnotatedTypes(Path, Init, Visit); + if (EnableLifetimeWarnings) + handleGslAnnotatedTypes(Path, Init, Visit); return visitLifetimeBoundArguments(Path, Init, Visit); } @@ -7047,7 +7070,8 @@ static void visitLocalsRetainedByInitial Path.push_back({IndirectLocalPathEntry::AddressOf, UO}); visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(), - RK_ReferenceBinding, Visit); + RK_ReferenceBinding, Visit, + EnableLifetimeWarnings); } break; } @@ -7060,9 +7084,11 @@ static void visitLocalsRetainedByInitial break; if (BO->getLHS()->getType()->isPointerType()) - visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true); + visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true, + EnableLifetimeWarnings); else if (BO->getRHS()->getType()->isPointerType()) - visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true); + visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true, + EnableLifetimeWarnings); break; } @@ -7072,9 +7098,11 @@ static void visitLocalsRetainedByInitial // In C++, we can have a throw-expression operand, which has 'void' type // and isn't interesting from a lifetime perspective. if (!C->getTrueExpr()->getType()->isVoidType()) - visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true); + visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true, + EnableLifetimeWarnings); if (!C->getFalseExpr()->getType()->isVoidType()) - visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true); + visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true, + EnableLifetimeWarnings); break; } @@ -7381,12 +7409,16 @@ void Sema::checkInitializerLifetime(cons return false; }; + bool EnableLifetimeWarnings = !getDiagnostics().isIgnored( + diag::warn_dangling_lifetime_pointer, SourceLocation()); llvm::SmallVector<IndirectLocalPathEntry, 8> Path; if (Init->isGLValue()) visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding, - TemporaryVisitor); + TemporaryVisitor, + EnableLifetimeWarnings); else - visitLocalsRetainedByInitializer(Path, Init, TemporaryVisitor, false); + visitLocalsRetainedByInitializer(Path, Init, TemporaryVisitor, false, + EnableLifetimeWarnings); } static void DiagnoseNarrowingInInitList(Sema &S, Added: cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp?rev=369817&view=auto ============================================================================== --- cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp (added) +++ cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg-disabled.cpp Fri Aug 23 15:21:33 2019 @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-dangling -Wreturn-stack-address -verify %s + +struct [[gsl::Owner(int)]] MyIntOwner { + MyIntOwner(); + int &operator*(); +}; + +struct [[gsl::Pointer(int)]] MyIntPointer { + MyIntPointer(int *p = nullptr); + MyIntPointer(const MyIntOwner &); + int &operator*(); + MyIntOwner toOwner(); +}; + +int &f() { + int i; + return i; // expected-warning {{reference to stack memory associated with local variable 'i' returned}} +} + +MyIntPointer g() { + MyIntOwner o; + return o; // No warning, it is disabled. +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits