@@ -36,6 +36,7 @@ namespace clang::dataflow {
36
36
37
37
namespace {
38
38
using namespace ast_matchers ;
39
+ using Diagnoser = NullCheckAfterDereferenceDiagnoser;
39
40
40
41
constexpr char kCond [] = " condition" ;
41
42
constexpr char kVar [] = " var" ;
@@ -423,9 +424,9 @@ void matchAnyPointerExpr(const Expr *fncall,
423
424
setUnknownValue (*Var, *RootValue, Env);
424
425
}
425
426
426
- NullCheckAfterDereferenceDiagnoser ::ResultType
427
+ Diagnoser ::ResultType
427
428
diagnoseDerefLocation (const Expr *Deref, const MatchFinder::MatchResult &Result,
428
- NullCheckAfterDereferenceDiagnoser ::DiagnoseArgs &Data) {
429
+ Diagnoser ::DiagnoseArgs &Data) {
429
430
auto [ValToDerefLoc, WarningLocToVal, Env] = Data;
430
431
431
432
const auto *Var = Result.Nodes .getNodeAs <Expr>(kVar );
@@ -444,10 +445,9 @@ diagnoseDerefLocation(const Expr *Deref, const MatchFinder::MatchResult &Result,
444
445
return {};
445
446
}
446
447
447
- NullCheckAfterDereferenceDiagnoser::ResultType
448
- diagnoseAssignLocation (const Expr *Assign,
449
- const MatchFinder::MatchResult &Result,
450
- NullCheckAfterDereferenceDiagnoser::DiagnoseArgs &Data) {
448
+ Diagnoser::ResultType diagnoseAssignLocation (const Expr *Assign,
449
+ const MatchFinder::MatchResult &Result,
450
+ Diagnoser::DiagnoseArgs &Data) {
451
451
auto [ValToDerefLoc, WarningLocToVal, Env] = Data;
452
452
453
453
const auto *RHSVar = Result.Nodes .getNodeAs <Expr>(kValue );
@@ -468,7 +468,7 @@ diagnoseAssignLocation(const Expr *Assign,
468
468
NullCheckAfterDereferenceDiagnoser::ResultType
469
469
diagnoseNullCheckExpr (const Expr *NullCheck,
470
470
const MatchFinder::MatchResult &Result,
471
- const NullCheckAfterDereferenceDiagnoser ::DiagnoseArgs &Data) {
471
+ const Diagnoser ::DiagnoseArgs &Data) {
472
472
auto [ValToDerefLoc, WarningLocToVal, Env] = Data;
473
473
474
474
const auto *Var = Result.Nodes .getNodeAs <Expr>(kVar );
@@ -488,7 +488,7 @@ diagnoseNullCheckExpr(const Expr *NullCheck,
488
488
assert (Inserted && " multiple warnings at the same source location" );
489
489
(void )Inserted;
490
490
491
- return {{}, { Var->getBeginLoc ()}};
491
+ return {{Var->getBeginLoc (), Diagnoser::DiagnosticType::CheckAfterDeref }};
492
492
}
493
493
494
494
if (IsNull && !IsNonnull) {
@@ -497,7 +497,7 @@ diagnoseNullCheckExpr(const Expr *NullCheck,
497
497
assert (Inserted && " multiple warnings at the same source location" );
498
498
(void )Inserted;
499
499
500
- return {{Var->getBeginLoc ()}, { }};
500
+ return {{Var->getBeginLoc (), Diagnoser::DiagnosticType::CheckWhenNull }};
501
501
}
502
502
}
503
503
@@ -513,7 +513,7 @@ diagnoseNullCheckExpr(const Expr *NullCheck,
513
513
514
514
NullCheckAfterDereferenceDiagnoser::ResultType
515
515
diagnoseEqualExpr (const Expr *PtrCheck, const MatchFinder::MatchResult &Result,
516
- NullCheckAfterDereferenceDiagnoser ::DiagnoseArgs &Data) {
516
+ Diagnoser ::DiagnoseArgs &Data) {
517
517
auto [ValToDerefLoc, WarningLocToVal, Env] = Data;
518
518
519
519
const auto *LHSVar = Result.Nodes .getNodeAs <Expr>(kVar );
@@ -522,23 +522,23 @@ diagnoseEqualExpr(const Expr *PtrCheck, const MatchFinder::MatchResult &Result,
522
522
assert (RHSVar != nullptr );
523
523
524
524
Arena &A = Env.arena ();
525
- std::vector<SourceLocation > NullVarLocations;
525
+ llvm::SmallVector<Diagnoser::DiagnosticEntry > NullVarLocations;
526
526
527
527
if (Value *LHSValue = Env.getValue (*LHSVar);
528
528
LHSValue->getProperty (kIsNonnull ) &&
529
529
Env.proves (A.makeNot (getVal (kIsNonnull , *LHSValue).formula ()))) {
530
530
WarningLocToVal.try_emplace (LHSVar->getBeginLoc (), LHSValue);
531
- NullVarLocations.push_back (LHSVar->getBeginLoc ());
531
+ NullVarLocations.push_back ({ LHSVar->getBeginLoc (), Diagnoser::DiagnosticType::CheckWhenNull} );
532
532
}
533
533
534
534
if (Value *RHSValue = Env.getValue (*RHSVar);
535
535
RHSValue->getProperty (kIsNonnull ) &&
536
536
Env.proves (A.makeNot (getVal (kIsNonnull , *RHSValue).formula ()))) {
537
537
WarningLocToVal.try_emplace (RHSVar->getBeginLoc (), RHSValue);
538
- NullVarLocations.push_back (RHSVar->getBeginLoc ());
538
+ NullVarLocations.push_back ({ RHSVar->getBeginLoc (), Diagnoser::DiagnosticType::CheckWhenNull} );
539
539
}
540
540
541
- return { NullVarLocations, {}} ;
541
+ return NullVarLocations;
542
542
}
543
543
544
544
auto buildTransferMatchSwitch () {
@@ -556,8 +556,7 @@ auto buildTransferMatchSwitch() {
556
556
}
557
557
558
558
auto buildDiagnoseMatchSwitch () {
559
- return CFGMatchSwitchBuilder<NullCheckAfterDereferenceDiagnoser::DiagnoseArgs,
560
- NullCheckAfterDereferenceDiagnoser::ResultType>()
559
+ return CFGMatchSwitchBuilder<Diagnoser::DiagnoseArgs, Diagnoser::ResultType>()
561
560
.CaseOfCFGStmt <Expr>(derefMatcher (), diagnoseDerefLocation)
562
561
.CaseOfCFGStmt <Expr>(arrowMatcher (), diagnoseDerefLocation)
563
562
.CaseOfCFGStmt <Expr>(assignMatcher (), diagnoseAssignLocation)
@@ -761,11 +760,11 @@ NullCheckAfterDereferenceDiagnoser::NullCheckAfterDereferenceDiagnoser()
761
760
: DiagnoseMatchSwitch(buildDiagnoseMatchSwitch()) {}
762
761
763
762
NullCheckAfterDereferenceDiagnoser::ResultType
764
- NullCheckAfterDereferenceDiagnoser::diagnose (ASTContext &Ctx,
765
- const CFGElement * Elt,
766
- const Environment &Env ) {
767
- DiagnoseArgs Args = {ValToDerefLoc, WarningLocToVal, Env};
768
- return DiagnoseMatchSwitch (* Elt, Ctx, Args);
763
+ NullCheckAfterDereferenceDiagnoser::operator ()(
764
+ const CFGElement & Elt, ASTContext &Ctx,
765
+ const TransferStateForDiagnostics<NoopLattice> &State ) {
766
+ DiagnoseArgs Args = {ValToDerefLoc, WarningLocToVal, State. Env };
767
+ return DiagnoseMatchSwitch (Elt, Ctx, Args);
769
768
}
770
769
771
770
} // namespace clang::dataflow
0 commit comments