Skip to content

Commit 6377d5d

Browse files
committed
[-Wunsafe-buffer-usage] Fix debug notes for unclaimed DREs (llvm#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. (cherry picked from commit 2f49058)
1 parent 136fc48 commit 6377d5d

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,34 +2864,41 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
28642864
it->first->getNameAsString() +
28652865
"' : has a reference type"));
28662866
#endif
2867-
it = FixablesForAllVars.byVar.erase(it);
2868-
} else if (Tracker.hasUnclaimedUses(it->first)) {
2869-
#ifndef NDEBUG
2870-
auto AllUnclaimed = Tracker.getUnclaimedUses(it->first);
2871-
for (auto UnclaimedDRE : AllUnclaimed) {
2872-
std::string UnclaimedUseTrace =
2873-
getDREAncestorString(UnclaimedDRE, D->getASTContext());
2874-
2875-
Handler.addDebugNoteForVar(
2876-
it->first, UnclaimedDRE->getBeginLoc(),
2877-
("failed to produce fixit for '" + it->first->getNameAsString() +
2878-
"' : has an unclaimed use\nThe unclaimed DRE trace: " +
2879-
UnclaimedUseTrace));
2880-
}
2881-
#endif
2882-
it = FixablesForAllVars.byVar.erase(it);
2883-
} else if (it->first->isInitCapture()) {
2867+
it = FixablesForAllVars.byVar.erase(it);
2868+
} else if (Tracker.hasUnclaimedUses(it->first)) {
2869+
it = FixablesForAllVars.byVar.erase(it);
2870+
} else if (it->first->isInitCapture()) {
28842871
#ifndef NDEBUG
28852872
Handler.addDebugNoteForVar(it->first, it->first->getBeginLoc(),
28862873
("failed to produce fixit for '" +
28872874
it->first->getNameAsString() +
28882875
"' : init capture"));
28892876
#endif
2890-
it = FixablesForAllVars.byVar.erase(it);
2891-
} else {
2892-
++it;
2877+
it = FixablesForAllVars.byVar.erase(it);
2878+
} else {
2879+
++it;
2880+
}
2881+
}
2882+
2883+
#ifndef NDEBUG
2884+
for (const auto &it : UnsafeOps.byVar) {
2885+
const VarDecl *const UnsafeVD = it.first;
2886+
auto UnclaimedDREs = Tracker.getUnclaimedUses(UnsafeVD);
2887+
if (UnclaimedDREs.empty())
2888+
continue;
2889+
const auto UnfixedVDName = UnsafeVD->getNameAsString();
2890+
for (const clang::DeclRefExpr *UnclaimedDRE : UnclaimedDREs) {
2891+
std::string UnclaimedUseTrace =
2892+
getDREAncestorString(UnclaimedDRE, D->getASTContext());
2893+
2894+
Handler.addDebugNoteForVar(
2895+
UnsafeVD, UnclaimedDRE->getBeginLoc(),
2896+
("failed to produce fixit for '" + UnfixedVDName +
2897+
"' : has an unclaimed use\nThe unclaimed DRE trace: " +
2898+
UnclaimedUseTrace));
28932899
}
28942900
}
2901+
#endif
28952902

28962903
// Fixpoint iteration for pointer assignments
28972904
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)