Skip to content

Commit 2f49058

Browse files
[-Wunsafe-buffer-usage] Fix debug notes for unclaimed DREs (#80787)
Debug notes for unclaimed DeclRefExpr should report any DRE of an unsafe variable that is not covered by a Fixable (i. e. fixit for the particular AST pattern isn't implemented for whatever reason). Currently not all unclaimed DeclRefExpr-s are reported which is a bug. The debug notes report only those DREs where the referred VarDecl has at least one other DeclRefExpr which is claimed (covered by a fixit). If there is an unsafe VarDecl that has exactly one DRE and the DRE isn't claimed then the debug note about missing fixit won't be emitted. That is because the debug note is emitted from within a loop over set of successfully matched FixableGadgets which by-definition is missing those DRE that are not matched at all. The new code simply iterates over all unsafe VarDecls and all of their unclaimed DREs.
1 parent 42357df commit 2f49058

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,19 +2870,6 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
28702870
#endif
28712871
it = FixablesForAllVars.byVar.erase(it);
28722872
} else if (Tracker.hasUnclaimedUses(it->first)) {
2873-
#ifndef NDEBUG
2874-
auto AllUnclaimed = Tracker.getUnclaimedUses(it->first);
2875-
for (auto UnclaimedDRE : AllUnclaimed) {
2876-
std::string UnclaimedUseTrace =
2877-
getDREAncestorString(UnclaimedDRE, D->getASTContext());
2878-
2879-
Handler.addDebugNoteForVar(
2880-
it->first, UnclaimedDRE->getBeginLoc(),
2881-
("failed to produce fixit for '" + it->first->getNameAsString() +
2882-
"' : has an unclaimed use\nThe unclaimed DRE trace: " +
2883-
UnclaimedUseTrace));
2884-
}
2885-
#endif
28862873
it = FixablesForAllVars.byVar.erase(it);
28872874
} else if (it->first->isInitCapture()) {
28882875
#ifndef NDEBUG
@@ -2892,10 +2879,30 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
28922879
"' : init capture"));
28932880
#endif
28942881
it = FixablesForAllVars.byVar.erase(it);
2895-
}else {
2896-
++it;
2882+
} else {
2883+
++it;
2884+
}
2885+
}
2886+
2887+
#ifndef NDEBUG
2888+
for (const auto &it : UnsafeOps.byVar) {
2889+
const VarDecl *const UnsafeVD = it.first;
2890+
auto UnclaimedDREs = Tracker.getUnclaimedUses(UnsafeVD);
2891+
if (UnclaimedDREs.empty())
2892+
continue;
2893+
const auto UnfixedVDName = UnsafeVD->getNameAsString();
2894+
for (const clang::DeclRefExpr *UnclaimedDRE : UnclaimedDREs) {
2895+
std::string UnclaimedUseTrace =
2896+
getDREAncestorString(UnclaimedDRE, D->getASTContext());
2897+
2898+
Handler.addDebugNoteForVar(
2899+
UnsafeVD, UnclaimedDRE->getBeginLoc(),
2900+
("failed to produce fixit for '" + UnfixedVDName +
2901+
"' : has an unclaimed use\nThe unclaimed DRE trace: " +
2902+
UnclaimedUseTrace));
28972903
}
28982904
}
2905+
#endif
28992906

29002907
// Fixpoint iteration for pointer assignments
29012908
using DepMapTy = DenseMap<const VarDecl *, llvm::SetVector<const VarDecl *>>;

clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,10 @@ void test_struct_claim_use() {
9898
x[6] = 8; // expected-warning{{unsafe buffer access}}
9999
x++; // expected-warning{{unsafe pointer arithmetic}}
100100
}
101+
102+
void use(int*);
103+
void array2d(int idx) {
104+
int buffer[10][5]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
105+
use(buffer[idx]); // expected-note{{used in buffer access here}} \
106+
// debug-note{{safe buffers debug: failed to produce fixit for 'buffer' : has an unclaimed use}}
107+
}

0 commit comments

Comments
 (0)