Skip to content

Commit 0f8d6dc

Browse files
authored
Merge pull request #292 from correctcomputation/RootCauseImprovements
Root cause of wildness improvements
2 parents 6ec85bc + d685ab5 commit 0f8d6dc

22 files changed

+528
-298
lines changed

clang-tools-extra/clangd/CConvertDiagnostics.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ bool CConvertDiagnostics::PopulateDiagsFromConstraintsInfo(ConstraintsInfo &Line
4444
return nRange;
4545
};
4646

47-
for (auto &WReason : Line.RealWildPtrsWithReasons) {
48-
if (Line.PtrSourceMap.find(WReason.first) != Line.PtrSourceMap.end()) {
49-
auto *PsInfo = Line.PtrSourceMap[WReason.first];
47+
for (auto &WReason : Line.RootWildAtomsWithReason) {
48+
if (Line.AtomSourceMap.find(WReason.first) != Line.AtomSourceMap.end()) {
49+
auto *PsInfo = Line.AtomSourceMap[WReason.first];
5050
std::string FilePath = PsInfo->getFileName();
5151
// If this is not a file in a project? Then ignore.
5252
if (!IsValidSourceFile(Line, FilePath))
@@ -61,15 +61,15 @@ bool CConvertDiagnostics::PopulateDiagsFromConstraintsInfo(ConstraintsInfo &Line
6161
NewDiag.Severity = DiagnosticsEngine::Level::Error;
6262
NewDiag.code = std::to_string(WReason.first);
6363
NewDiag.Message = "Pointer is wild because of:" +
64-
WReason.second.WildPtrReason;
64+
WReason.second.getWildPtrReason();
6565

6666
// Create notes for the information about root cause.
67-
if (WReason.second.IsValid) {
67+
PersistentSourceLoc SL = WReason.second.getLocation();
68+
if (SL.valid()) {
6869
Note DiagNote;
69-
DiagNote.AbsFile = WReason.second.SourceFileName;
70+
DiagNote.AbsFile = SL.getFileName();
7071
DiagNote.Range =
71-
GetLocRange(WReason.second.LineNo, WReason.second.ColStartS,
72-
WReason.second.ColStartE);
72+
GetLocRange(SL.getLineNo(), SL.getColSNo(), SL.getColENo());
7373
DiagNote.Message = "Go here to know the root cause for this.";
7474
NewDiag.Notes.push_back(DiagNote);
7575
}
@@ -78,11 +78,11 @@ bool CConvertDiagnostics::PopulateDiagsFromConstraintsInfo(ConstraintsInfo &Line
7878
}
7979

8080
// For non-direct wild pointers..update the reason and diag information.
81-
for (auto NonWildCk : Line.TotalNonDirectWildPointers) {
81+
for (auto NonWildCk : Line.TotalNonDirectWildAtoms) {
8282
if (ProcessedCKeys.find(NonWildCk) == ProcessedCKeys.end()) {
8383
ProcessedCKeys.insert(NonWildCk);
84-
if (Line.PtrSourceMap.find(NonWildCk) != Line.PtrSourceMap.end()) {
85-
auto *PsInfo = Line.PtrSourceMap[NonWildCk];
84+
if (Line.AtomSourceMap.find(NonWildCk) != Line.AtomSourceMap.end()) {
85+
auto *PsInfo = Line.AtomSourceMap[NonWildCk];
8686
std::string FilePath = PsInfo->getFileName();
8787
// If this is not a file in a project? Then ignore.
8888
if (!IsValidSourceFile(Line, FilePath))
@@ -106,15 +106,15 @@ bool CConvertDiagnostics::PopulateDiagsFromConstraintsInfo(ConstraintsInfo &Line
106106
for (auto tC : DirectWildPtrs) {
107107
Note DiagNote;
108108

109-
if (Line.PtrSourceMap.find(tC) != Line.PtrSourceMap.end()) {
110-
PsInfo = Line.PtrSourceMap[tC];
109+
if (Line.AtomSourceMap.find(tC) != Line.AtomSourceMap.end()) {
110+
PsInfo = Line.AtomSourceMap[tC];
111111
FilePath = PsInfo->getFileName();
112112
DiagNote.AbsFile = FilePath;
113113
DiagNote.Range =
114114
GetLocRange(PsInfo->getLineNo(), PsInfo->getColSNo(),
115115
PsInfo->getColENo());
116116
MaxPtrReasons--;
117-
DiagNote.Message = Line.RealWildPtrsWithReasons[tC].WildPtrReason;
117+
DiagNote.Message = Line.RootWildAtomsWithReason[tC].getWildPtrReason();
118118
if (MaxPtrReasons <= 1)
119119
DiagNote.Message += " (others)";
120120
NewDiag.Notes.push_back(DiagNote);

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ void ClangdServer::executeCConvCommand(ExecuteCommandParams Params,
211211
auto Task = [this, Params, ConvCB]() {
212212
std::string RplMsg;
213213
auto &WildPtrsInfo = CConvInter.GetWILDPtrsInfo();
214-
auto &PtrSourceMap = WildPtrsInfo.PtrSourceMap;
214+
auto &PtrSourceMap = WildPtrsInfo.AtomSourceMap;
215215
if (PtrSourceMap.find(Params.ccConvertManualFix->ptrID) !=
216216
PtrSourceMap.end()) {
217217
std::string PtrFileName =

clang-tools-extra/clangd/tool/ClangdMain.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,20 @@ static llvm::cl::opt<std::string>
331331
llvm::cl::init("TotalConstraintStats.json"),
332332
llvm::cl::cat(ConvertCategory));
333333

334-
static llvm::cl::opt<std::string>
334+
static cl::opt<std::string>
335335
OptWildPtrInfoJson("wildptrstats-output",
336-
llvm::cl::desc("Path to the file where all the info "
337-
"related to WILD ptr will be dumped as json"),
338-
llvm::cl::init("WildPtrStats.json"),
339-
llvm::cl::cat(ConvertCategory));
336+
cl::desc("Path to the file where all the info "
337+
"related to WILD ptr grouped by reason"
338+
" will be dumped as json"),
339+
cl::init("WildPtrStats.json"),
340+
cl::cat(ConvertCategory));
341+
342+
static cl::opt<std::string>
343+
OptPerPtrWILDInfoJson("perptrstats-output",
344+
cl::desc("Path to the file where all the info "
345+
"related to each WILD ptr will be dumped as json"),
346+
cl::init("PerWildPtrStats.json"),
347+
cl::cat(ConvertCategory));
340348

341349
static llvm::cl::opt<bool>
342350
OptDiableCCTypeChecker("disccty",
@@ -465,6 +473,7 @@ int main(int argc, char *argv[]) {
465473
CcOptions.DumpIntermediate = DumpIntermediate;
466474
CcOptions.ConstraintOutputJson = ConstraintOutputJson.getValue();
467475
CcOptions.WildPtrInfoJson = OptWildPtrInfoJson.getValue();
476+
CcOptions.PerPtrInfoJson = OptPerPtrWILDInfoJson.getValue();
468477
CcOptions.StatsOutputJson = OptStatsOutputJson.getValue();
469478
CcOptions.AddCheckedRegions = AddCheckedRegions;
470479
CcOptions.EnableAllTypes = AllTypes;

clang/include/clang/CConv/CConv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ struct CConvertOptions {
3838

3939
std::string WildPtrInfoJson;
4040

41+
std::string PerPtrInfoJson;
42+
4143
std::vector<std::string> AllocatorFunctions;
4244

4345
bool HandleVARARGS;

clang/include/clang/CConv/CConvInteractiveData.h

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
1717
#include "PersistentSourceLoc.h"
1818

1919
// Source info and reason for each wild pointer.
20-
struct WildPointerInferenceInfo {
21-
std::string SourceFileName = "";
20+
class WildPointerInferenceInfo {
21+
public:
22+
WildPointerInferenceInfo(std::string Reason, const PersistentSourceLoc PSL) :
23+
WildPtrReason(Reason), Location(PSL) {}
24+
25+
const std::string &getWildPtrReason() const { return WildPtrReason; }
26+
const PersistentSourceLoc &getLocation() const { return Location; }
27+
28+
private:
2229
std::string WildPtrReason = "";
23-
bool IsValid = false;
24-
unsigned LineNo = 0;
25-
unsigned ColStartS = 0;
26-
unsigned ColStartE = 0;
30+
PersistentSourceLoc Location;
2731
};
2832

2933
// Constraints information.
@@ -37,16 +41,17 @@ class ConstraintsInfo {
3741
CVars &GetRCVars(ConstraintKey);
3842
CVars &GetSrcCVars(ConstraintKey);
3943
CVars getWildAffectedCKeys(const std::set<ConstraintKey> &DWKeys);
40-
void print_stats(llvm::raw_ostream &O);
44+
void printStats(llvm::raw_ostream &O);
45+
void printRootCauseStats(raw_ostream &O, Constraints &CS);
46+
int getNumPtrsAffected(ConstraintKey CK);
4147

42-
std::map<ConstraintKey, struct WildPointerInferenceInfo>
43-
RealWildPtrsWithReasons;
44-
CVars AllWildPtrs;
45-
CVars InSrcWildPtrs;
46-
CVars TotalNonDirectWildPointers;
47-
CVars InSrcNonDirectWildPointers;
48+
std::map<ConstraintKey, WildPointerInferenceInfo> RootWildAtomsWithReason;
49+
CVars AllWildAtoms;
50+
CVars InSrcWildAtoms;
51+
CVars TotalNonDirectWildAtoms;
52+
CVars InSrcNonDirectWildAtoms;
4853
std::set<std::string> ValidSourceFiles;
49-
std::map<ConstraintKey, PersistentSourceLoc *> PtrSourceMap;
54+
std::map<ConstraintKey, const PersistentSourceLoc *> AtomSourceMap;
5055

5156
private:
5257
// Root cause map: This is the map of a Constraint var and a set of
@@ -67,6 +72,20 @@ class ConstraintsInfo {
6772
// the above constraint.
6873
// For the above case, this contains: p -> {s}, q -> {r, s}
6974
std::map<ConstraintKey, CVars> SrcWMap;
75+
76+
std::map<ConstraintVariable *, CVars> PtrRCMap;
77+
std::map<ConstraintKey, std::set<ConstraintVariable *>> PtrSrcWMap;
78+
79+
// Get score for each of the ConstraintKeys, which are wild.
80+
// For the above example, the score of s would be 0.5, similarly
81+
// the score of r would be 1
82+
float getAtomAffectedScore(const CVars &AllKeys);
83+
84+
float getPtrAffectedScore(const std::set<ConstraintVariable *> CVs);
85+
86+
void
87+
printConstraintStats(raw_ostream &O, Constraints &CS, ConstraintKey Cause);
88+
7089
};
7190

7291
#endif // _CCONVINTERACTIVEDATA_H

clang/include/clang/CConv/ConstraintResolver.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,11 @@ class ConstraintResolver {
6060

6161
CVarSet handleDeref(CVarSet T);
6262

63-
CVarSet getInvalidCastPVCons(Expr *E);
63+
CVarSet getInvalidCastPVCons(CastExpr *E);
6464

6565
// Update a PVConstraint with one additional level of indirection
6666
PVConstraint *addAtom(PVConstraint *PVC, ConstAtom *NewA, Constraints &CS);
6767
CVarSet addAtomAll(CVarSet CVS, ConstAtom *PtrTyp, Constraints &CS);
68-
CVarSet getWildPVConstraint();
6968
CVarSet PVConstraintFromType(QualType TypE);
7069

7170
CVarSet getAllSubExprConstraintVars(std::vector<Expr *> &Exprs);

clang/include/clang/CConv/ConstraintVariables.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ class PointerVariableConstraint : public ConstraintVariable {
204204
RestrictQualification
205205
};
206206

207-
static PointerVariableConstraint *getWildPVConstraint(Constraints &CS);
207+
static PointerVariableConstraint *
208+
getWildPVConstraint(Constraints &CS, const std::string &Rsn,
209+
PersistentSourceLoc *PSL = nullptr);
208210
static PointerVariableConstraint *getPtrPVConstraint(Constraints &CS);
209211
static PointerVariableConstraint *getNonPtrPVConstraint(Constraints &CS);
210212
static PointerVariableConstraint *getNamedNonPtrPVConstraint(StringRef name, Constraints &CS);

clang/include/clang/CConv/Constraints.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,11 @@ class Constraint {
321321
};
322322
private:
323323
const ConstraintKind Kind;
324+
PersistentSourceLoc PL;
325+
324326
public:
325327
std::string REASON = DEFAULT_REASON;
326-
std::string FileName = "";
327-
unsigned LineNo = 0;
328-
unsigned ColStart = 0;
329-
unsigned ColEnd = 0;
328+
330329
Constraint(ConstraintKind K) : Kind(K) { }
331330
Constraint(ConstraintKind K, const std::string &rsn) : Kind(K) {
332331
REASON = rsn;
@@ -349,6 +348,8 @@ class Constraint {
349348
virtual void setReason(const std::string &Rsn) {
350349
REASON = Rsn;
351350
}
351+
352+
const PersistentSourceLoc &getLocation() const { return PL; }
352353
};
353354

354355
// a >= b
@@ -579,7 +580,7 @@ class Constraints {
579580

580581
void editConstraintHook(Constraint *C);
581582

582-
std::pair<Constraints::ConstraintSet, bool> solve();
583+
void solve();
583584
void dump() const;
584585
void print(llvm::raw_ostream &) const;
585586
void dump_json(llvm::raw_ostream &) const;
@@ -591,6 +592,10 @@ class Constraints {
591592
PersistentSourceLoc *PL, bool isCheckedConstraint = true);
592593
Implies *createImplies(Geq *Premise, Geq *Conclusion);
593594

595+
VarAtom *createFreshGEQ(std::string Name, VarAtom::VarKind VK, ConstAtom *Con,
596+
std::string Rsn = DEFAULT_REASON,
597+
PersistentSourceLoc *PSL = nullptr);
598+
594599
VarAtom *getFreshVar(std::string Name, VarAtom::VarKind VK);
595600
VarAtom *getOrCreateVar(ConstraintKey V, std::string Name,
596601
VarAtom::VarKind VK);
@@ -630,7 +635,7 @@ class Constraints {
630635
VarSolTy getDefaultSolution();
631636

632637
// Solve constraint set via graph-based dynamic transitive closure
633-
bool graph_based_solve(ConstraintSet &Conflicts);
638+
bool graph_based_solve();
634639

635640
// These atoms can be singletons, so we'll store them in the
636641
// Constraints class.

clang/include/clang/CConv/PersistentSourceLoc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class PersistentSourceLoc {
3838
uint32_t getLineNo() const { return LineNo; }
3939
uint32_t getColSNo() const { return ColNoS; }
4040
uint32_t getColENo() const { return ColNoE; }
41-
bool valid() { return isValid; }
41+
bool valid() const { return isValid; }
4242

4343
bool operator<(const PersistentSourceLoc &o) const {
4444
if (FileName == o.FileName)

clang/include/clang/CConv/ProgramInfo.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ class ProgramInfo : public ProgramVariableAdder {
114114
const CallTypeParamBindingsT &getTypeParamBindings(CallExpr *CE,
115115
ASTContext *C) const;
116116

117-
void constrainWildIfMacro(ConstraintVariable *CV, SourceLocation Location);
117+
void constrainWildIfMacro(ConstraintVariable *CV, SourceLocation Location,
118+
PersistentSourceLoc *PSL = nullptr);
118119

119120
private:
120121
// List of constraint variables for declarations, indexed by their location in
@@ -184,6 +185,14 @@ class ProgramInfo : public ProgramVariableAdder {
184185
// For each pointer type in the declaration of D, add a variable to the
185186
// constraint system for that pointer type.
186187
void addVariable(clang::DeclaratorDecl *D, clang::ASTContext *AstContext);
188+
189+
void insertIntoPtrSourceMap(const PersistentSourceLoc *PSL,
190+
ConstraintVariable *CV);
191+
192+
void computePtrLevelStats();
193+
194+
void insertCVAtoms(ConstraintVariable *CV,
195+
std::map<ConstraintKey, ConstraintVariable *> &AtomMap);
187196
};
188197

189198
#endif

clang/include/clang/CConv/RewriteUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class RewriteConsumer : public ASTConsumer {
226226
// A single header file can be included in multiple translations units. This
227227
// set ensures that the diagnostics for a header file are not emitted each
228228
// time a translation unit containing the header is vistied.
229-
static std::set<PersistentSourceLoc *> EmittedDiagnostics;
229+
static std::set<PersistentSourceLoc> EmittedDiagnostics;
230230

231231
void emitRootCauseDiagnostics(ASTContext &Context);
232232
};

0 commit comments

Comments
 (0)