@@ -1176,11 +1176,7 @@ groupWarningGadgetsByVar(const WarningGadgetList &AllUnsafeOperations) {
1176
1176
}
1177
1177
1178
1178
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;
1184
1180
};
1185
1181
1186
1182
static FixableGadgetSets
@@ -1386,7 +1382,7 @@ static std::optional<StringRef> getRangeText(SourceRange SR,
1386
1382
const SourceManager &SM,
1387
1383
const LangOptions &LangOpts) {
1388
1384
bool Invalid = false ;
1389
- CharSourceRange CSR = CharSourceRange::getCharRange (SR);
1385
+ CharSourceRange CSR = CharSourceRange::getCharRange (SR. getBegin (), SR. getEnd () );
1390
1386
StringRef Text = Lexer::getSourceText (CSR, SM, LangOpts, &Invalid);
1391
1387
1392
1388
if (!Invalid)
@@ -2229,7 +2225,7 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
2229
2225
ASTContext &Ctx,
2230
2226
/* The function decl under analysis */ const Decl *D,
2231
2227
const DeclUseTracker &Tracker, UnsafeBufferUsageHandler &Handler,
2232
- const VariableGroupsManager &VarGrpMgr ) {
2228
+ const DefMapTy &VarGrpMap ) {
2233
2229
std::map<const VarDecl *, FixItList> FixItsForVariable;
2234
2230
for (const auto &[VD, Fixables] : FixablesForAllVars.byVar ) {
2235
2231
FixItsForVariable[VD] =
@@ -2265,10 +2261,9 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
2265
2261
continue ;
2266
2262
}
2267
2263
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 ) {
2272
2267
if (V == VD) {
2273
2268
continue ;
2274
2269
}
@@ -2280,7 +2275,7 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
2280
2275
2281
2276
if (ImpossibleToFix) {
2282
2277
FixItsForVariable.erase (VD);
2283
- for (const VarDecl * V : VarGroupForVD) {
2278
+ for (const VarDecl * V : VarGroupForVD-> second ) {
2284
2279
FixItsForVariable.erase (V);
2285
2280
}
2286
2281
continue ;
@@ -2298,24 +2293,30 @@ getFixIts(FixableGadgetSets &FixablesForAllVars, const Strategy &S,
2298
2293
}
2299
2294
}
2300
2295
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
+ }
2305
2304
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
+ }
2308
2312
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
+ }
2316
2317
}
2317
2318
}
2318
- return FinalFixItsForVariable ;
2319
+ return FixItsForVariable ;
2319
2320
}
2320
2321
2321
2322
@@ -2328,24 +2329,6 @@ getNaiveStrategy(const llvm::SmallVectorImpl<const VarDecl *> &UnsafeVars) {
2328
2329
return S;
2329
2330
}
2330
2331
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
-
2349
2332
void clang::checkUnsafeBufferUsage (const Decl *D,
2350
2333
UnsafeBufferUsageHandler &Handler,
2351
2334
bool EmitSuggestions) {
@@ -2425,6 +2408,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
2425
2408
FixablesForAllVars = groupFixablesByVar (std::move (FixableGadgets));
2426
2409
2427
2410
std::map<const VarDecl *, FixItList> FixItsForVariableGroup;
2411
+ DefMapTy VariableGroupsMap{};
2428
2412
2429
2413
// Filter out non-local vars and vars with unclaimed DeclRefExpr-s.
2430
2414
for (auto it = FixablesForAllVars.byVar .cbegin ();
@@ -2467,7 +2451,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
2467
2451
UnsafeVars.push_back (VD);
2468
2452
2469
2453
// 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 *>>;
2471
2455
DepMapTy DependenciesMap{};
2472
2456
DepMapTy PtrAssignmentGraph{};
2473
2457
@@ -2476,7 +2460,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
2476
2460
std::optional<std::pair<const VarDecl *, const VarDecl *>> ImplPair =
2477
2461
fixable->getStrategyImplications ();
2478
2462
if (ImplPair) {
2479
- std::pair<const VarDecl *, const VarDecl *> Impl = std::move (* ImplPair);
2463
+ std::pair<const VarDecl *, const VarDecl *> Impl = ImplPair. value ( );
2480
2464
PtrAssignmentGraph[Impl.first ].insert (Impl.second );
2481
2465
}
2482
2466
}
@@ -2521,21 +2505,14 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
2521
2505
}
2522
2506
}
2523
2507
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
-
2531
2508
// Group Connected Components for Unsafe Vars
2532
2509
// (Dependencies based on pointer assignments)
2533
2510
std::set<const VarDecl *> VisitedVars{};
2534
2511
for (const auto &[Var, ignore] : UnsafeOps.byVar ) {
2535
2512
if (VisitedVars.find (Var) == VisitedVars.end ()) {
2536
- VarGrpTy &VarGroup = Groups.emplace_back ();
2537
- std::queue<const VarDecl*> Queue{};
2513
+ std::vector<const VarDecl *> VarGroup{};
2538
2514
2515
+ std::queue<const VarDecl*> Queue{};
2539
2516
Queue.push (Var);
2540
2517
while (!Queue.empty ()) {
2541
2518
const VarDecl* CurrentVar = Queue.front ();
@@ -2549,10 +2526,10 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
2549
2526
}
2550
2527
}
2551
2528
}
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
+ }
2556
2533
}
2557
2534
}
2558
2535
}
@@ -2586,19 +2563,20 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
2586
2563
}
2587
2564
2588
2565
Strategy NaiveStrategy = getNaiveStrategy (UnsafeVars);
2589
- VariableGroupsManagerImpl VarGrpMgr (Groups, VarGrpMap);
2590
2566
2591
2567
FixItsForVariableGroup =
2592
2568
getFixIts (FixablesForAllVars, NaiveStrategy, D->getASTContext (), D,
2593
- Tracker, Handler, VarGrpMgr);
2569
+ Tracker, Handler, VariableGroupsMap);
2570
+
2571
+ // FIXME Detect overlapping FixIts.
2594
2572
2595
2573
for (const auto &G : UnsafeOps.noVar ) {
2596
2574
Handler.handleUnsafeOperation (G->getBaseStmt (), /* IsRelatedToDecl=*/ false );
2597
2575
}
2598
2576
2599
2577
for (const auto &[VD, WarningGadgets] : UnsafeOps.byVar ) {
2600
2578
auto FixItsIt = FixItsForVariableGroup.find (VD);
2601
- Handler.handleUnsafeVariableGroup (VD, VarGrpMgr ,
2579
+ Handler.handleUnsafeVariableGroup (VD, VariableGroupsMap ,
2602
2580
FixItsIt != FixItsForVariableGroup.end ()
2603
2581
? std::move (FixItsIt->second )
2604
2582
: FixItList{});
0 commit comments