Skip to content

Commit d64278c

Browse files
committed
fix-missing-lifetimeends-for-params
1 parent d44d329 commit d64278c

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

clang/lib/Analysis/CFG.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,16 @@ std::unique_ptr<CFG> CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) {
16661666
assert(Succ == &cfg->getExit());
16671667
Block = nullptr; // the EXIT block is empty. Create all other blocks lazily.
16681668

1669+
// Add parameters to the initial scope so that their lifetime is handled
1670+
// correctly.
1671+
LocalScope *paramScope = nullptr;
1672+
if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D))
1673+
for (ParmVarDecl *PD : FD->parameters())
1674+
paramScope = addLocalScopeForVarDecl(PD, paramScope);
1675+
else if (const auto *BD = dyn_cast_or_null<BlockDecl>(D))
1676+
for (ParmVarDecl *PD : BD->parameters())
1677+
paramScope = addLocalScopeForVarDecl(PD, paramScope);
1678+
16691679
if (BuildOpts.AddImplicitDtors)
16701680
if (const CXXDestructorDecl *DD = dyn_cast_or_null<CXXDestructorDecl>(D))
16711681
addImplicitDtorsForDestructor(DD);
@@ -2246,6 +2256,9 @@ LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD,
22462256
if (!VD->hasLocalStorage())
22472257
return Scope;
22482258

2259+
if (isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType())
2260+
return Scope;
2261+
22492262
if (!BuildOpts.AddLifetime && !BuildOpts.AddScopes &&
22502263
!needsAutomaticDestruction(VD)) {
22512264
assert(BuildOpts.AddImplicitDtors);

clang/test/Sema/warn-lifetime-safety.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,14 +529,14 @@ TriviallyDestructedClass* trivial_class_uar () {
529529
return ptr; // expected-note {{returned here}}
530530
}
531531

532-
// FIXME: No lifetime warning for this as no expire facts are generated for parameters
533532
const int& return_parameter(int a) {
534-
return a;
533+
return a; // expected-warning {{address of stack memory is returned later}}
534+
// expected-note@-1 {{returned here}}
535535
}
536536

537-
// FIXME: No lifetime warning for this as no expire facts are generated for parameters
538537
int* return_pointer_to_parameter(int a) {
539-
return &a;
538+
return &a; // expected-warning {{address of stack memory is returned later}}
539+
// expected-note@-1 {{returned here}}
540540
}
541541

542542
const int& return_reference_to_parameter(int a)
@@ -788,9 +788,9 @@ const MyObj& lifetimebound_return_ref_to_local() {
788788
// expected-note@-1 {{returned here}}
789789
}
790790

791-
// FIXME: Fails to diagnose UAR when a reference to a by-value param escapes via the return value.
792791
View lifetimebound_return_of_by_value_param(MyObj stack_param) {
793-
return Identity(stack_param);
792+
return Identity(stack_param); // expected-warning {{address of stack memory is returned later}}
793+
// expected-note@-1 {{returned here}}
794794
}
795795

796796
// FIXME: Fails to diagnose UAF when a reference to a by-value param escapes via an out-param.

0 commit comments

Comments
 (0)