Skip to content

Commit ac9a76d

Browse files
committed
Revert "[-Wunsafe-buffer-usage][NFC] Slightly refactor and optimize the code"
This reverts commit 8437847. There is a build failure caused by this commit.
1 parent 8f4a0b7 commit ac9a76d

File tree

3 files changed

+86
-118
lines changed

3 files changed

+86
-118
lines changed

clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,7 @@
2020

2121
namespace clang {
2222

23-
using VarGrpTy = std::vector<const VarDecl *>;
24-
using VarGrpRef = ArrayRef<const VarDecl *>;
25-
26-
class VariableGroupsManager {
27-
public:
28-
VariableGroupsManager() = default;
29-
virtual ~VariableGroupsManager() = default;
30-
/// Returns the set of variables (including `Var`) that need to be fixed
31-
/// together in one step.
32-
///
33-
/// `Var` must be a variable that needs fix (so it must be in a group).
34-
virtual VarGrpRef getGroupOfVar(const VarDecl *Var) const;
35-
};
23+
using DefMapTy = llvm::DenseMap<const VarDecl *, std::vector<const VarDecl *>>;
3624

3725
/// The interface that lets the caller handle unsafe buffer usage analysis
3826
/// results by overriding this class's handle... methods.
@@ -65,7 +53,7 @@ class UnsafeBufferUsageHandler {
6553
/// all variables that must be fixed together (i.e their types must be changed to the
6654
/// same target type to prevent type mismatches) into a single fixit.
6755
virtual void handleUnsafeVariableGroup(const VarDecl *Variable,
68-
const VariableGroupsManager &VarGrpMgr,
56+
const DefMapTy &VarGrpMap,
6957
FixItList &&Fixes) = 0;
7058

7159
#ifndef NDEBUG

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 40 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,11 +1176,7 @@ groupWarningGadgetsByVar(const WarningGadgetList &AllUnsafeOperations) {
11761176
}
11771177

11781178
struct FixableGadgetSets {
1179-
std::map<const VarDecl *, std::set<const FixableGadget *>,
1180-
// To keep keys sorted by their locations in the map so that the
1181-
// order is deterministic:
1182-
CompareNode<VarDecl>>
1183-
byVar;
1179+
std::map<const VarDecl *, std::set<const FixableGadget *>> byVar;
11841180
};
11851181

11861182
static FixableGadgetSets
@@ -1386,7 +1382,7 @@ static std::optional<StringRef> getRangeText(SourceRange SR,
13861382
const SourceManager &SM,
13871383
const LangOptions &LangOpts) {
13881384
bool Invalid = false;
1389-
CharSourceRange CSR = CharSourceRange::getCharRange(SR);
1385+
CharSourceRange CSR = CharSourceRange::getCharRange(SR.getBegin(), SR.getEnd());
13901386
StringRef Text = Lexer::getSourceText(CSR, SM, LangOpts, &Invalid);
13911387

13921388
if (!Invalid)
@@ -2229,7 +2225,7 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
22292225
ASTContext &Ctx,
22302226
/* The function decl under analysis */ const Decl *D,
22312227
const DeclUseTracker &Tracker, UnsafeBufferUsageHandler &Handler,
2232-
const VariableGroupsManager &VarGrpMgr) {
2228+
const DefMapTy &VarGrpMap) {
22332229
std::map<const VarDecl *, FixItList> FixItsForVariable;
22342230
for (const auto &[VD, Fixables] : FixablesForAllVars.byVar) {
22352231
FixItsForVariable[VD] =
@@ -2265,10 +2261,9 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
22652261
continue;
22662262
}
22672263

2268-
2269-
{
2270-
const auto VarGroupForVD = VarGrpMgr.getGroupOfVar(VD);
2271-
for (const VarDecl * V : VarGroupForVD) {
2264+
const auto VarGroupForVD = VarGrpMap.find(VD);
2265+
if (VarGroupForVD != VarGrpMap.end()) {
2266+
for (const VarDecl * V : VarGroupForVD->second) {
22722267
if (V == VD) {
22732268
continue;
22742269
}
@@ -2280,7 +2275,7 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
22802275

22812276
if (ImpossibleToFix) {
22822277
FixItsForVariable.erase(VD);
2283-
for (const VarDecl * V : VarGroupForVD) {
2278+
for (const VarDecl * V : VarGroupForVD->second) {
22842279
FixItsForVariable.erase(V);
22852280
}
22862281
continue;
@@ -2298,24 +2293,30 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
22982293
}
22992294
}
23002295

2301-
// The map that maps each variable `v` to fix-its for the whole group where
2302-
// `v` is in:
2303-
std::map<const VarDecl *, FixItList> FinalFixItsForVariable{
2304-
FixItsForVariable};
2296+
for (auto VD : FixItsForVariable) {
2297+
const auto VarGroupForVD = VarGrpMap.find(VD.first);
2298+
const Strategy::Kind ReplacementTypeForVD = S.lookup(VD.first);
2299+
if (VarGroupForVD != VarGrpMap.end()) {
2300+
for (const VarDecl * Var : VarGroupForVD->second) {
2301+
if (Var == VD.first) {
2302+
continue;
2303+
}
23052304

2306-
for (auto &[Var, Ignore] : FixItsForVariable) {
2307-
const auto VarGroupForVD = VarGrpMgr.getGroupOfVar(Var);
2305+
FixItList GroupFix;
2306+
if (FixItsForVariable.find(Var) == FixItsForVariable.end()) {
2307+
GroupFix = fixVariable(Var, ReplacementTypeForVD, D, Tracker,
2308+
Var->getASTContext(), Handler);
2309+
} else {
2310+
GroupFix = FixItsForVariable[Var];
2311+
}
23082312

2309-
for (const VarDecl *GrpMate : VarGroupForVD) {
2310-
if (Var == GrpMate)
2311-
continue;
2312-
if (FixItsForVariable.count(GrpMate))
2313-
FinalFixItsForVariable[Var].insert(FinalFixItsForVariable[Var].end(),
2314-
FixItsForVariable[GrpMate].begin(),
2315-
FixItsForVariable[GrpMate].end());
2313+
for (auto Fix : GroupFix) {
2314+
FixItsForVariable[VD.first].push_back(Fix);
2315+
}
2316+
}
23162317
}
23172318
}
2318-
return FinalFixItsForVariable;
2319+
return FixItsForVariable;
23192320
}
23202321

23212322

@@ -2328,24 +2329,6 @@ getNaiveStrategy(const llvm::SmallVectorImpl<const VarDecl *> &UnsafeVars) {
23282329
return S;
23292330
}
23302331

2331-
// Manages variable groups:
2332-
class VariableGroupsManagerImpl : public VariableGroupsManager {
2333-
const std::vector<VarGrpTy> Groups;
2334-
const std::map<const VarDecl *, unsigned> &VarGrpMap;
2335-
2336-
public:
2337-
VariableGroupsManagerImpl(
2338-
const std::vector<VarGrpTy> &Groups,
2339-
const std::map<const VarDecl *, unsigned> &VarGrpMap)
2340-
: Groups(Groups), VarGrpMap(VarGrpMap) {}
2341-
2342-
VarGrpRef getGroupOfVar(const VarDecl *Var) const override {
2343-
auto I = VarGrpMap.find(Var);
2344-
assert(I != VarGrpMap.end());
2345-
return Groups[I->second];
2346-
}
2347-
};
2348-
23492332
void clang::checkUnsafeBufferUsage(const Decl *D,
23502333
UnsafeBufferUsageHandler &Handler,
23512334
bool EmitSuggestions) {
@@ -2425,6 +2408,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
24252408
FixablesForAllVars = groupFixablesByVar(std::move(FixableGadgets));
24262409

24272410
std::map<const VarDecl *, FixItList> FixItsForVariableGroup;
2411+
DefMapTy VariableGroupsMap{};
24282412

24292413
// Filter out non-local vars and vars with unclaimed DeclRefExpr-s.
24302414
for (auto it = FixablesForAllVars.byVar.cbegin();
@@ -2467,7 +2451,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
24672451
UnsafeVars.push_back(VD);
24682452

24692453
// Fixpoint iteration for pointer assignments
2470-
using DepMapTy = DenseMap<const VarDecl *, llvm::SetVector<const VarDecl *>>;
2454+
using DepMapTy = DenseMap<const VarDecl *, std::set<const VarDecl *>>;
24712455
DepMapTy DependenciesMap{};
24722456
DepMapTy PtrAssignmentGraph{};
24732457

@@ -2476,7 +2460,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
24762460
std::optional<std::pair<const VarDecl *, const VarDecl *>> ImplPair =
24772461
fixable->getStrategyImplications();
24782462
if (ImplPair) {
2479-
std::pair<const VarDecl *, const VarDecl *> Impl = std::move(*ImplPair);
2463+
std::pair<const VarDecl *, const VarDecl *> Impl = ImplPair.value();
24802464
PtrAssignmentGraph[Impl.first].insert(Impl.second);
24812465
}
24822466
}
@@ -2521,21 +2505,14 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
25212505
}
25222506
}
25232507

2524-
// `Groups` stores the set of Connected Components in the graph.
2525-
std::vector<VarGrpTy> Groups;
2526-
// `VarGrpMap` maps variables that need fix to the groups (indexes) that the
2527-
// variables belong to. Group indexes refer to the elements in `Groups`.
2528-
// `VarGrpMap` is complete in that every variable that needs fix is in it.
2529-
std::map<const VarDecl *, unsigned> VarGrpMap;
2530-
25312508
// Group Connected Components for Unsafe Vars
25322509
// (Dependencies based on pointer assignments)
25332510
std::set<const VarDecl *> VisitedVars{};
25342511
for (const auto &[Var, ignore] : UnsafeOps.byVar) {
25352512
if (VisitedVars.find(Var) == VisitedVars.end()) {
2536-
VarGrpTy &VarGroup = Groups.emplace_back();
2537-
std::queue<const VarDecl*> Queue{};
2513+
std::vector<const VarDecl *> VarGroup{};
25382514

2515+
std::queue<const VarDecl*> Queue{};
25392516
Queue.push(Var);
25402517
while(!Queue.empty()) {
25412518
const VarDecl* CurrentVar = Queue.front();
@@ -2549,10 +2526,10 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
25492526
}
25502527
}
25512528
}
2552-
unsigned GrpIdx = Groups.size() - 1;
2553-
2554-
for (const VarDecl *V : VarGroup) {
2555-
VarGrpMap[V] = GrpIdx;
2529+
for (const VarDecl * V : VarGroup) {
2530+
if (UnsafeOps.byVar.find(V) != UnsafeOps.byVar.end()) {
2531+
VariableGroupsMap[V] = VarGroup;
2532+
}
25562533
}
25572534
}
25582535
}
@@ -2586,19 +2563,20 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
25862563
}
25872564

25882565
Strategy NaiveStrategy = getNaiveStrategy(UnsafeVars);
2589-
VariableGroupsManagerImpl VarGrpMgr(Groups, VarGrpMap);
25902566

25912567
FixItsForVariableGroup =
25922568
getFixIts(FixablesForAllVars, NaiveStrategy, D->getASTContext(), D,
2593-
Tracker, Handler, VarGrpMgr);
2569+
Tracker, Handler, VariableGroupsMap);
2570+
2571+
// FIXME Detect overlapping FixIts.
25942572

25952573
for (const auto &G : UnsafeOps.noVar) {
25962574
Handler.handleUnsafeOperation(G->getBaseStmt(), /*IsRelatedToDecl=*/false);
25972575
}
25982576

25992577
for (const auto &[VD, WarningGadgets] : UnsafeOps.byVar) {
26002578
auto FixItsIt = FixItsForVariableGroup.find(VD);
2601-
Handler.handleUnsafeVariableGroup(VD, VarGrpMgr,
2579+
Handler.handleUnsafeVariableGroup(VD, VariableGroupsMap,
26022580
FixItsIt != FixItsForVariableGroup.end()
26032581
? std::move(FixItsIt->second)
26042582
: FixItList{});

clang/lib/Sema/AnalysisBasedWarnings.cpp

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,41 +2175,6 @@ class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler {
21752175
Sema &S;
21762176
bool SuggestSuggestions; // Recommend -fsafe-buffer-usage-suggestions?
21772177

2178-
// Lists as a string the names of variables in `VarGroupForVD` except for `VD`
2179-
// itself:
2180-
std::string listVariableGroupAsString(
2181-
const VarDecl *VD, const ArrayRef<const VarDecl *> &VarGroupForVD) const {
2182-
if (VarGroupForVD.size() <= 1)
2183-
return "";
2184-
2185-
std::vector<StringRef> VarNames;
2186-
auto PutInQuotes = [](StringRef S) -> std::string {
2187-
return "'" + S.str() + "'";
2188-
};
2189-
2190-
for (auto *V : VarGroupForVD) {
2191-
if (V == VD)
2192-
continue;
2193-
VarNames.push_back(V->getName());
2194-
}
2195-
if (VarNames.size() == 1) {
2196-
return PutInQuotes(VarNames[0]);
2197-
}
2198-
if (VarNames.size() == 2) {
2199-
return PutInQuotes(VarNames[0]) + " and " + PutInQuotes(VarNames[1]);
2200-
}
2201-
assert(VarGroupForVD.size() > 3);
2202-
const unsigned N = VarNames.size() -
2203-
2; // need to print the last two names as "..., X, and Y"
2204-
std::string AllVars = "";
2205-
2206-
for (unsigned I = 0; I < N; ++I)
2207-
AllVars.append(PutInQuotes(VarNames[I]) + ", ");
2208-
AllVars.append(PutInQuotes(VarNames[N]) + ", and " +
2209-
PutInQuotes(VarNames[N + 1]));
2210-
return AllVars;
2211-
}
2212-
22132178
public:
22142179
UnsafeBufferUsageReporter(Sema &S, bool SuggestSuggestions)
22152180
: S(S), SuggestSuggestions(SuggestSuggestions) {}
@@ -2266,25 +2231,62 @@ class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler {
22662231
}
22672232

22682233
void handleUnsafeVariableGroup(const VarDecl *Variable,
2269-
const VariableGroupsManager &VarGrpMgr,
2270-
FixItList &&Fixes) override {
2234+
const DefMapTy &VarGrpMap,
2235+
FixItList &&Fixes) override {
22712236
assert(!SuggestSuggestions &&
22722237
"Unsafe buffer usage fixits displayed without suggestions!");
22732238
S.Diag(Variable->getLocation(), diag::warn_unsafe_buffer_variable)
22742239
<< Variable << (Variable->getType()->isPointerType() ? 0 : 1)
22752240
<< Variable->getSourceRange();
22762241
if (!Fixes.empty()) {
2277-
const auto VarGroupForVD = VarGrpMgr.getGroupOfVar(Variable);
2242+
const auto VarGroupForVD = VarGrpMap.find(Variable)->second;
22782243
unsigned FixItStrategy = 0; // For now we only have 'std::span' strategy
22792244
const auto &FD = S.Diag(Variable->getLocation(),
22802245
diag::note_unsafe_buffer_variable_fixit_group);
22812246

22822247
FD << Variable << FixItStrategy;
2283-
FD << listVariableGroupAsString(Variable, VarGroupForVD)
2284-
<< (VarGroupForVD.size() > 1);
2285-
for (const auto &F : Fixes) {
2286-
FD << F;
2248+
std::string AllVars = "";
2249+
if (VarGroupForVD.size() > 1) {
2250+
if (VarGroupForVD.size() == 2) {
2251+
if (VarGroupForVD[0] == Variable) {
2252+
AllVars.append("'" + VarGroupForVD[1]->getName().str() + "'");
2253+
} else {
2254+
AllVars.append("'" + VarGroupForVD[0]->getName().str() + "'");
2255+
}
2256+
} else {
2257+
bool first = false;
2258+
if (VarGroupForVD.size() == 3) {
2259+
for (const VarDecl * V : VarGroupForVD) {
2260+
if (V == Variable) {
2261+
continue;
2262+
}
2263+
if (!first) {
2264+
first = true;
2265+
AllVars.append("'" + V->getName().str() + "'" + " and ");
2266+
} else {
2267+
AllVars.append("'" + V->getName().str() + "'");
2268+
}
2269+
}
2270+
} else {
2271+
for (const VarDecl * V : VarGroupForVD) {
2272+
if (V == Variable) {
2273+
continue;
2274+
}
2275+
if (VarGroupForVD.back() != V) {
2276+
AllVars.append("'" + V->getName().str() + "'" + ", ");
2277+
} else {
2278+
AllVars.append("and '" + V->getName().str() + "'");
2279+
}
2280+
}
2281+
}
2282+
}
2283+
FD << AllVars << 1;
2284+
} else {
2285+
FD << "" << 0;
22872286
}
2287+
2288+
for (const auto &F : Fixes)
2289+
FD << F;
22882290
}
22892291

22902292
#ifndef NDEBUG

0 commit comments

Comments
 (0)