Skip to content

Commit 026b659

Browse files
authored
Merge pull request #245 from plum-umd/SingletonSetRefactoring
Refactoring to remove singleton ConstraintVariable sets
2 parents 198d0f3 + eac4521 commit 026b659

14 files changed

+422
-610
lines changed

clang/include/clang/CConv/CheckedRegions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ class CheckedRegionFinder : public clang::RecursiveASTVisitor<CheckedRegionFinde
8383
bool containsUncheckedPtr(clang::QualType Qt);
8484
bool containsUncheckedPtrAcc(clang::QualType Qt, std::set<std::string> &Seen);
8585
bool isUncheckedStruct(clang::QualType Qt, std::set<std::string> &Seen);
86-
bool isWild(std::set<ConstraintVariable*>&);
87-
bool isWild(std::set<FVConstraint*>*);
86+
bool isWild(const std::set<ConstraintVariable*>&);
87+
bool isWild(const std::set<FVConstraint*>*);
8888

8989
clang::ASTContext* Context;
9090
clang::Rewriter& Writer;

clang/include/clang/CConv/ConstraintResolver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ class ConstraintResolver {
4646

4747
// Check if the set contains any valid constraints.
4848
bool containsValidCons(CVarSet &CVs);
49+
bool isValidCons(ConstraintVariable *CV);
4950
// Try to get the bounds key from the constraint variable set.
5051
bool resolveBoundsKey(CVarSet &CVs, BoundsKey &BK);
52+
bool resolveBoundsKey(ConstraintVariable *CV, BoundsKey &BK);
5153

5254
static bool canFunctionBeSkipped(const std::string &FN);
5355

clang/include/clang/CConv/ConstraintVariables.h

Lines changed: 104 additions & 101 deletions
Large diffs are not rendered by default.

clang/include/clang/CConv/ProgramInfo.h

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,18 @@ class ProgramInfo : public ProgramVariableAdder {
4545
typedef std::map<PersistentSourceLoc, CallTypeParamBindingsT>
4646
TypeParamBindingsT;
4747

48-
typedef std::map<std::string, std::map<std::string, std::set<FVConstraint *>>>
49-
StaticFunctionMapType;
5048

51-
typedef std::map<std::string, std::set<FVConstraint *>>
52-
ExternalFunctionMapType;
49+
typedef std::map<std::string, FVConstraint *> ExternalFunctionMapType;
50+
typedef std::map<std::string, ExternalFunctionMapType> StaticFunctionMapType;
5351

5452
ProgramInfo();
5553
void print(llvm::raw_ostream &O) const;
5654
void dump() const { print(llvm::errs()); }
5755
void dump_json(llvm::raw_ostream &O) const;
58-
void dump_stats(std::set<std::string> &F) { print_stats(F, llvm::errs()); }
59-
void print_stats(std::set<std::string> &F, llvm::raw_ostream &O,
56+
void dump_stats(const std::set<std::string> &F) {
57+
print_stats(F, llvm::errs());
58+
}
59+
void print_stats(const std::set<std::string> &F, llvm::raw_ostream &O,
6060
bool OnlySummary = false, bool JsonFormat = false);
6161

6262
// Populate Variables, VarDeclToStatement, RVariables, and DepthMap with
@@ -69,16 +69,15 @@ class ProgramInfo : public ProgramVariableAdder {
6969
// should all be empty.
7070
void exitCompilationUnit();
7171

72-
CVarSet
73-
&getPersistentConstraintVars(Expr *E, ASTContext *AstContext);
72+
CVarSet &getPersistentConstraintVars(Expr *E, ASTContext *AstContext);
7473
// Get constraint variable for the provided Decl
75-
CVarSet getVariable(clang::Decl *D,
76-
clang::ASTContext *C);
74+
CVarSet getVariable(clang::Decl *D, clang::ASTContext *C);
7775

7876
// Retrieve a function's constraints by decl, or by name; nullptr if not found
79-
std::set<FVConstraint *> *getFuncConstraints(FunctionDecl *D, ASTContext *C);
80-
std::set<FVConstraint *> *getExtFuncDefnConstraintSet(std::string FuncName);
81-
std::set<FVConstraint *> *getStaticFuncConstraintSet(std::string FuncName, std::string FileName);
77+
FVConstraint *getFuncConstraint (FunctionDecl *D, ASTContext *C) const;
78+
FVConstraint *getExtFuncDefnConstraint (std::string FuncName) const;
79+
FVConstraint *getStaticFuncConstraint(std::string FuncName,
80+
std::string FileName) const;
8281

8382
// Check if the given function is an extern function.
8483
bool isAnExternFunction(const std::string &FName);
@@ -93,26 +92,27 @@ class ProgramInfo : public ProgramVariableAdder {
9392
AVarBoundsInfo &getABoundsInfo() { return ArrBInfo; }
9493

9594
// Parameter map is used for cast insertion, post-rewriting
96-
void merge_MF(ParameterMap &MF);
95+
void merge_MF(const ParameterMap &MF);
9796
ParameterMap &getMF();
9897

9998
ConstraintsInfo &getInterimConstraintState() {
10099
return CState;
101100
}
102-
bool computeInterimConstraintState(std::set<std::string> &FilePaths);
101+
bool computeInterimConstraintState(const std::set<std::string> &FilePaths);
103102

104-
ExternalFunctionMapType &getExternFuncDefFVMap() {
103+
const ExternalFunctionMapType &getExternFuncDefFVMap() const {
105104
return ExternalFunctionFVCons;
106105
}
107106

108-
StaticFunctionMapType &getStaticFuncDefFVMap() {
107+
const StaticFunctionMapType &getStaticFuncDefFVMap() const {
109108
return StaticFunctionFVCons;
110109
}
111110

112111
void setTypeParamBinding(CallExpr *CE, unsigned int TypeVarIdx,
113112
ConstraintVariable *CV, ASTContext *C);
114-
bool hasTypeParamBindings(CallExpr *CE, ASTContext *C);
115-
CallTypeParamBindingsT &getTypeParamBindings(CallExpr *CE, ASTContext *C);
113+
bool hasTypeParamBindings(CallExpr *CE, ASTContext *C) const;
114+
const CallTypeParamBindingsT &getTypeParamBindings(CallExpr *CE,
115+
ASTContext *C) const;
116116

117117
void constrainWildIfMacro(CVarSet &S, SourceLocation Location);
118118

@@ -156,14 +156,14 @@ class ProgramInfo : public ProgramVariableAdder {
156156
// Returns true if successful else false.
157157
bool insertIntoExternalFunctionMap(ExternalFunctionMapType &Map,
158158
const std::string &FuncName,
159-
std::set<FVConstraint *> &ToIns);
159+
FVConstraint *ToIns);
160160

161161
// Inserts the given FVConstraint* set into the provided static map.
162162
// Returns true if successful else false.
163163
bool insertIntoStaticFunctionMap(StaticFunctionMapType &Map,
164164
const std::string &FuncName,
165165
const std::string &FileName,
166-
std::set<FVConstraint *> &ToIns);
166+
FVConstraint *ToIns);
167167

168168

169169
// Special-case handling for decl introductions. For the moment this covers:
@@ -173,14 +173,12 @@ class ProgramInfo : public ProgramVariableAdder {
173173

174174
// Inserts the given FVConstraint* set into the global map, depending
175175
// on whether static or not; returns true on success
176-
bool
177-
insertNewFVConstraints(FunctionDecl *FD, std::set<FVConstraint *> &FVcons,
178-
ASTContext *C);
179-
180-
// Retrieves a FVConstraint* based on the decl (which could be static,
181-
// or global)
182-
std::set<FVConstraint *> *getFuncFVConstraints(FunctionDecl *FD,
183-
ASTContext *C);
176+
bool insertNewFVConstraint(FunctionDecl *FD, FVConstraint *FVCon,
177+
ASTContext *C);
178+
179+
// Retrieves a FVConstraint* from a Decl (which could be static, or global)
180+
FVConstraint *getFuncFVConstraint(FunctionDecl *FD, ASTContext *C);
181+
184182
// For each pointer type in the declaration of D, add a variable to the
185183
// constraint system for that pointer type.
186184
void addVariable(clang::DeclaratorDecl *D, clang::ASTContext *astContext);

clang/include/clang/CConv/Utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class BiMap {
6161
extern std::set<std::string> FilePaths;
6262

6363
template <typename T>
64-
T getOnly(std::set<T> &singletonSet) {
64+
T getOnly(const std::set<T> &singletonSet) {
6565
assert(singletonSet.size() == 1);
6666
return (*singletonSet.begin());
6767
}

clang/lib/CConv/AVarBoundsInfo.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ void AVarBoundsInfo::insertProgramVar(BoundsKey NK, ProgramVar *PV) {
333333
PVarInfo[NK] = PV;
334334
}
335335

336-
bool hasArray(CVarSet &CSet, Constraints &CS) {
336+
bool hasArray(const CVarSet &CSet, Constraints &CS) {
337337
auto &E = CS.getVariables();
338338
for (auto *CK : CSet) {
339339
if (PVConstraint *PV = dyn_cast<PVConstraint>(CK)) {
@@ -346,7 +346,7 @@ bool hasArray(CVarSet &CSet, Constraints &CS) {
346346
return false;
347347
}
348348

349-
bool isInSrcArray(CVarSet &CSet, Constraints &CS) {
349+
bool isInSrcArray(const CVarSet &CSet, Constraints &CS) {
350350
auto &E = CS.getVariables();
351351
for (auto *CK : CSet) {
352352
if (PVConstraint *PV = dyn_cast<PVConstraint>(CK)) {
@@ -673,17 +673,17 @@ bool AVarBoundsInfo::performFlowAnalysis(ProgramInfo *PI) {
673673
bool IsStatic = std::get<2>(ParmTup);
674674
unsigned ParmNum = std::get<3>(ParmTup);
675675
FVConstraint *FV = nullptr;
676-
if (IsStatic || !PI->getExtFuncDefnConstraintSet(FuncName)) {
677-
FV = getOnly(*(PI->getStaticFuncConstraintSet(FuncName, FileName)));
676+
if (IsStatic || !PI->getExtFuncDefnConstraint(FuncName)) {
677+
FV = PI->getStaticFuncConstraint(FuncName, FileName);
678678
} else {
679-
FV = getOnly(*(PI->getExtFuncDefnConstraintSet(FuncName)));
679+
FV = PI->getExtFuncDefnConstraint(FuncName);
680680
}
681681

682-
if (hasArray(FV->getParamVar(ParmNum), CS)) {
682+
if (hasArray({FV->getParamVar(ParmNum)}, CS)) {
683683
ArrPointers.insert(Bkey);
684684
}
685685
// Does this array belongs to a valid program variable?
686-
if (isInSrcArray(FV->getParamVar(ParmNum), CS)) {
686+
if (isInSrcArray({FV->getParamVar(ParmNum)}, CS)) {
687687
InProgramArrPtrBoundsKeys.insert(Bkey);
688688
}
689689

clang/lib/CConv/CastPlacement.cpp

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -20,58 +20,46 @@ bool CastPlacementVisitor::VisitCallExpr(CallExpr *CE) {
2020
auto *FD = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl());
2121
if (FD && Rewriter::isRewritable(CE->getExprLoc())) {
2222
// Get the constraint variable for the function.
23-
std::set<FVConstraint *> *V = Info.getFuncConstraints(FD, Context);
23+
FVConstraint *FV = Info.getFuncConstraint(FD, Context);
2424
// Function has no definition i.e., external function.
25-
assert("Function has no definition" && V != nullptr);
25+
assert("Function has no definition" && FV != nullptr);
2626

2727
// Did we see this function in another file?
2828
auto Fname = FD->getNameAsString();
29-
if (!V->empty() && !ConstraintResolver::canFunctionBeSkipped(Fname)) {
30-
// Get the FV constraint for the Callee.
31-
// TODO: This seems to assume that V is a singleton set. Validate this
32-
// assumption and use getOnly.
33-
if (FVConstraint *FV = *(V->begin())) {
34-
// Now we need to check the type of the arguments and corresponding
35-
// parameters to see if any explicit casting is needed.
36-
ProgramInfo::CallTypeParamBindingsT TypeVars;
37-
if (Info.hasTypeParamBindings(CE, Context))
38-
TypeVars = Info.getTypeParamBindings(CE, Context);
39-
auto PInfo = Info.getMF()[Fname];
40-
unsigned PIdx = 0;
41-
for (const auto &A : CE->arguments()) {
42-
if (PIdx < FD->getNumParams()) {
29+
if (!ConstraintResolver::canFunctionBeSkipped(Fname)) {
30+
// Now we need to check the type of the arguments and corresponding
31+
// parameters to see if any explicit casting is needed.
32+
ProgramInfo::CallTypeParamBindingsT TypeVars;
33+
if (Info.hasTypeParamBindings(CE, Context))
34+
TypeVars = Info.getTypeParamBindings(CE, Context);
35+
auto PInfo = Info.getMF()[Fname];
36+
unsigned PIdx = 0;
37+
for (const auto &A : CE->arguments()) {
38+
if (PIdx < FD->getNumParams()) {
39+
// Avoid adding incorrect casts to generic function arguments by
40+
// removing implicit casts when on arguments with a consistently
41+
// used generic type.
42+
Expr *ArgExpr = A;
43+
const TypeVariableType
44+
*TyVar = getTypeVariableType(FD->getParamDecl(PIdx));
45+
if (TyVar && TypeVars.find(TyVar->GetIndex()) != TypeVars.end()
46+
&& TypeVars[TyVar->GetIndex()] != nullptr)
47+
ArgExpr = ArgExpr->IgnoreImpCasts();
4348

44-
// Avoid adding incorrect casts to generic function arguments by
45-
// removing implicit casts when on arguments with a consistently
46-
// used generic type.
47-
Expr *ArgExpr = A;
48-
const TypeVariableType
49-
*TyVar = getTypeVariableType(FD->getParamDecl(PIdx));
50-
if (TyVar && TypeVars.find(TyVar->GetIndex()) != TypeVars.end()
51-
&& TypeVars[TyVar->GetIndex()] != nullptr)
52-
ArgExpr = ArgExpr->IgnoreImpCasts();
53-
54-
CVarSet ArgumentConstraints = CR.getExprConstraintVars(ArgExpr);
55-
CVarSet &ParameterConstraints = FV->getParamVar(PIdx);
56-
for (auto *ArgumentC : ArgumentConstraints) {
57-
bool CastInserted = false;
58-
for (auto *ParameterC : ParameterConstraints) {
59-
auto Dinfo = PIdx < PInfo.size() ? PInfo[PIdx] : CHECKED;
60-
if (needCasting(ArgumentC, ParameterC, Dinfo)) {
61-
// We expect the cast string to end with "(".
62-
std::string CastString =
63-
getCastString(ArgumentC, ParameterC, Dinfo);
64-
surroundByCast(CastString, A);
65-
CastInserted = true;
66-
break;
67-
}
68-
}
69-
// If we have already inserted a cast, then break.
70-
if (CastInserted) break;
49+
CVarSet ArgumentConstraints = CR.getExprConstraintVars(ArgExpr);
50+
ConstraintVariable *ParameterC = FV->getParamVar(PIdx);
51+
for (auto *ArgumentC : ArgumentConstraints) {
52+
auto Dinfo = PIdx < PInfo.size() ? PInfo[PIdx] : CHECKED;
53+
if (needCasting(ArgumentC, ParameterC, Dinfo)) {
54+
// We expect the cast string to end with "(".
55+
std::string CastString =
56+
getCastString(ArgumentC, ParameterC, Dinfo);
57+
surroundByCast(CastString, A);
58+
break;
7159
}
7260
}
73-
PIdx++;
7461
}
62+
PIdx++;
7563
}
7664
}
7765
}

clang/lib/CConv/CheckedRegions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ bool CheckedRegionFinder::VisitDeclRefExpr(DeclRefExpr* DR) {
235235
bool IW = isWild(CVSet ) || containsUncheckedPtr(T);
236236

237237
if (auto FD = dyn_cast<FunctionDecl>(D)) {
238-
auto FV = Info.getFuncConstraints(FD, Context);
239-
IW |= isWild(FV);
238+
auto *FV = Info.getFuncConstraint(FD, Context);
239+
IW |= FV->hasWild(Info.getConstraints().getVariables());
240240
for (const auto& param: FD->parameters()) {
241241
auto CVSet = Info.getVariable(param, Context);
242242
IW |= isWild(CVSet);
@@ -298,15 +298,15 @@ bool CheckedRegionFinder::isInStatementPosition(CallExpr *C) {
298298
}
299299
}
300300

301-
bool CheckedRegionFinder::isWild(std::set<ConstraintVariable*> &S) {
301+
bool CheckedRegionFinder::isWild(const std::set<ConstraintVariable*> &S) {
302302
for (auto Cv : S)
303303
if (Cv->hasWild(Info.getConstraints().getVariables()))
304304
return true;
305305

306306
return false;
307307
}
308308

309-
bool CheckedRegionFinder::isWild(std::set<FVConstraint*> *S) {
309+
bool CheckedRegionFinder::isWild(const std::set<FVConstraint*> *S) {
310310
for (auto Fv : *S)
311311
if (Fv->hasWild(Info.getConstraints().getVariables()))
312312
return true;

clang/lib/CConv/ConstraintBuilder.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,12 @@ class FunctionVisitor : public RecursiveASTVisitor<FunctionVisitor> {
214214
if (callUntyped) {
215215
deferred.push_back(ArgumentConstraints);
216216
} else if (i < TargetFV->numParams()) {
217-
// constrain the arg CV to the param CV
218-
CVarSet ParameterDC =
219-
TargetFV->getParamVar(i);
217+
// constrain the arg CV to the param CV
218+
ConstraintVariable *ParameterDC = TargetFV->getParamVar(i);
220219
constrainConsVarGeq(ParameterDC, ArgumentConstraints, CS, &PL,
221220
Wild_to_Safe, false, &Info);
222221
if (AllTypes && TFD != nullptr &&
223-
!CB.containsValidCons(ParameterDC) &&
222+
!CB.isValidCons(ParameterDC) &&
224223
!CB.containsValidCons(ArgumentConstraints)) {
225224
auto *PVD = TFD->getParamDecl(i);
226225
auto &ABI = Info.getABoundsInfo();
@@ -285,9 +284,8 @@ class FunctionVisitor : public RecursiveASTVisitor<FunctionVisitor> {
285284
if (FVConstraint *FV = dyn_cast<FVConstraint>(F)) {
286285
// This is to ensure that the return type of the function is same
287286
// as the type of return expression.
288-
constrainConsVarGeq(FV->getReturnVars(), RconsVar,
289-
Info.getConstraints(), &PL, Same_to_Same, false,
290-
&Info);
287+
constrainConsVarGeq(FV->getReturnVar(), RconsVar, Info.getConstraints(),
288+
&PL, Same_to_Same, false, &Info);
291289
}
292290
}
293291
return true;

0 commit comments

Comments
 (0)