Skip to content

Commit 4adb099

Browse files
committed
check member narrowing in isExprNullable for nonnull argument passing
1 parent 357ae33 commit 4adb099

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

clang/lib/Analysis/FlowNullability.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,18 @@ class TransferFunctions {
12941294
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
12951295
return isVarNullable(VD);
12961296
}
1297+
// Member narrowing: this->member or var.member narrowed by null check
1298+
if (const auto *ME = dyn_cast<MemberExpr>(E)) {
1299+
if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
1300+
const Expr *Base = ME->getBase()->IgnoreParenImpCasts();
1301+
if (isa<CXXThisExpr>(Base) && isThisMemberNarrowed(FD))
1302+
return false;
1303+
if (const auto *BaseDRE = dyn_cast<DeclRefExpr>(Base))
1304+
if (const auto *BaseVD = dyn_cast<VarDecl>(BaseDRE->getDecl()))
1305+
if (isMemberNarrowed(BaseVD, FD))
1306+
return false;
1307+
}
1308+
}
12971309
// For non-variable expressions, fall back to type-based check
12981310
if (isNullableType(E->getType(), StrictMode, DefaultNullability))
12991311
return true;

clang/test/SemaCXX/flow-nullability-adoption.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,18 @@ struct MemberNarrowObj {
367367
if (arr == nullptr) return;
368368
(void)arr[getMember()]; // OK - function call as index doesn't affect base narrowing
369369
}
370+
371+
// Passing narrowed member to _Nonnull parameter
372+
static void accept_nonnull(int * _Nonnull p);
373+
void test_member_nonnull_arg_after_check() {
374+
if (arr == nullptr) return;
375+
accept_nonnull(arr); // OK - member narrowed, safe to pass to _Nonnull
376+
}
377+
378+
void test_member_nonnull_arg_no_check() {
379+
accept_nonnull(arr); // expected-warning {{nullable pointer}} \
380+
// expected-note {{add a null check}}
381+
}
370382
};
371383

372384
// --- sizeof/alignof don't dereference ---

0 commit comments

Comments
 (0)