Skip to content

Commit 6ec85bc

Browse files
authored
Merge pull request #291 from correctcomputation/MiscRefactorings
Refactoring and bug fix changes
2 parents 119788b + c9b999c commit 6ec85bc

File tree

7 files changed

+64
-73
lines changed

7 files changed

+64
-73
lines changed

clang/include/clang/CConv/ConstraintVariables.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ class ConstraintVariable {
112112
virtual bool solutionEqualTo(Constraints &, const ConstraintVariable *) const
113113
= 0;
114114

115-
// Constrain all pointers in this ConstraintVariable to be Wild.
116-
virtual void constrainToWild(Constraints &CS) const = 0;
117115
virtual void constrainToWild(Constraints &CS,
118116
const std::string &Rsn) const = 0;
119117
virtual void constrainToWild(Constraints &CS, const std::string &Rsn,
@@ -362,7 +360,7 @@ class PointerVariableConstraint : public ConstraintVariable {
362360
void print(llvm::raw_ostream &O) const override ;
363361
void dump() const override { print(llvm::errs()); }
364362
void dump_json(llvm::raw_ostream &O) const override;
365-
void constrainToWild(Constraints &CS) const override;
363+
366364
void constrainToWild(Constraints &CS, const std::string &Rsn) const override;
367365
void constrainToWild(Constraints &CS, const std::string &Rsn,
368366
PersistentSourceLoc *PL) const override;
@@ -477,7 +475,7 @@ class FunctionVariableConstraint : public ConstraintVariable {
477475
void print(llvm::raw_ostream &O) const override;
478476
void dump() const override { print(llvm::errs()); }
479477
void dump_json(llvm::raw_ostream &O) const override;
480-
void constrainToWild(Constraints &CS) const override;
478+
481479
void constrainToWild(Constraints &CS, const std::string &Rsn) const override;
482480
void constrainToWild(Constraints &CS, const std::string &Rsn,
483481
PersistentSourceLoc *PL) const override;

clang/include/clang/CConv/DeclRewriter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class DeclRewriter {
6868
void doDeclRewrite(SourceRange &SR, DeclReplacement *N);
6969

7070
void rewriteFunctionDecl(FunctionDeclReplacement *N);
71-
void getDeclsOnSameLine(DeclReplacement *N, std::set<Decl *> &Decls);
71+
void getDeclsOnSameLine(DeclReplacement *N, std::vector<Decl *> &Decls);
7272
bool isSingleDeclaration(DeclReplacement *N);
7373
bool areDeclarationsOnSameLine(DeclReplacement *N1, DeclReplacement *N2);
7474
SourceRange getNextCommaOrSemicolon(SourceLocation L);

clang/include/clang/CConv/RewriteUtils.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,15 @@ typedef std::set<DeclReplacement *, DComp> RSet;
186186
class GlobalVariableGroups {
187187
public:
188188
GlobalVariableGroups(SourceManager &SourceMgr) : SM(SourceMgr) { }
189-
void addGlobalDecl(Decl *VD, std::set<Decl *> *VDSet = nullptr);
189+
void addGlobalDecl(Decl *VD, std::vector<Decl *> *VDVec = nullptr);
190190

191-
std::set<Decl *> &getVarsOnSameLine(Decl *VD);
191+
std::vector<Decl *> &getVarsOnSameLine(Decl *VD);
192192

193193
virtual ~GlobalVariableGroups();
194194

195195
private:
196196
SourceManager &SM;
197-
std::map<Decl *, std::set<Decl *>*> GlobVarGroups;
197+
std::map<Decl *, std::vector<Decl *>*> GlobVarGroups;
198198
};
199199

200200
// Class that handles rewriting bounds information for all the

clang/lib/CConv/ConstraintResolver.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ CVarSet
434434
QualType ExprType = E->getType();
435435
Decl *D = CE->getCalleeDecl();
436436
CVarSet ReallocFlow;
437+
bool IsAllocator = false;
437438
if (D == nullptr) {
438439
// There are a few reasons that we couldn't get a decl. For example,
439440
// the call could be done through an array subscript.
@@ -452,6 +453,7 @@ CVarSet
452453
/* Allocator call */
453454
if (isFunctionAllocator(FD->getName())) {
454455
bool didInsert = false;
456+
IsAllocator = true;
455457
if (CE->getNumArgs() > 0) {
456458
QualType ArgTy;
457459
std::string FuncName = FD->getNameAsString();
@@ -509,19 +511,24 @@ CVarSet
509511
for (ConstraintVariable *CV : ReturnCVs) {
510512
ConstraintVariable *NewCV;
511513
auto *PCV = dyn_cast<PVConstraint>(CV);
512-
if (PCV && PCV->getIsOriginallyChecked()) {
513-
// Copying needs to be done differently if the constraint variable
514-
// had a checked type in the input program because these constraint
515-
// variables contain constant atoms that are reused by the copy
516-
// constructor.
517-
NewCV = new PVConstraint(CE->getType(), nullptr, PCV->getName(),
518-
Info, *Context, nullptr,
519-
PCV->getIsGeneric());
520-
if (PCV->hasBoundsKey())
521-
NewCV->setBoundsKey(PCV->getBoundsKey());
522-
514+
if (!IsAllocator) {
515+
if (PCV && PCV->getIsOriginallyChecked()) {
516+
// Copying needs to be done differently if the constraint variable
517+
// had a checked type in the input program because the constraint
518+
// variables contain constant atoms that are reused by the copy
519+
// constructor.
520+
NewCV = new PVConstraint(CE->getType(), nullptr, PCV->getName(),
521+
Info, *Context, nullptr,
522+
PCV->getIsGeneric());
523+
if (PCV->hasBoundsKey())
524+
NewCV->setBoundsKey(PCV->getBoundsKey());
525+
} else {
526+
NewCV = CV->getCopy(CS);
527+
}
523528
} else {
524-
NewCV = CV->getCopy(CS);
529+
// Allocator functions are treated specially, so they do not have
530+
// separate parameter and argument return variables.
531+
NewCV = CV;
525532
}
526533

527534
// Make the bounds key context sensitive.
@@ -535,8 +542,9 @@ CVarSet
535542

536543
// Important: Do Safe_to_Wild from returnvar in this copy, which then
537544
// might be assigned otherwise (Same_to_Same) to LHS
538-
constrainConsVarGeq(NewCV, CV, CS, nullptr, Safe_to_Wild, false,
539-
&Info);
545+
if (NewCV != CV)
546+
constrainConsVarGeq(NewCV, CV, CS, nullptr, Safe_to_Wild, false,
547+
&Info);
540548
TmpCVs.insert(NewCV);
541549
// If this is realloc, constrain the first arg to flow to the return
542550
if (!ReallocFlow.empty()) {

clang/lib/CConv/ConstraintVariables.cpp

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -880,19 +880,9 @@ FunctionVariableConstraint::FunctionVariableConstraint(const Type *Ty,
880880
ReturnVar = new PVConstraint(RT, D, RETVAR, I, Ctx, &N, IsGeneric);
881881
}
882882

883-
void FunctionVariableConstraint::constrainToWild(Constraints &CS) const {
884-
ReturnVar->constrainToWild(CS);
885-
886-
for (const auto &V : ParamVars)
887-
V->constrainToWild(CS);
888-
}
889-
890883
void FunctionVariableConstraint::constrainToWild(Constraints &CS,
891884
const std::string &Rsn) const {
892-
ReturnVar->constrainToWild(CS, Rsn);
893-
894-
for (const auto &V : ParamVars)
895-
V->constrainToWild(CS, Rsn);
885+
constrainToWild(CS, Rsn, nullptr);
896886
}
897887

898888
void FunctionVariableConstraint::constrainToWild
@@ -975,41 +965,26 @@ void FunctionVariableConstraint::equateArgumentConstraints(ProgramInfo &Info) {
975965
}
976966
}
977967

978-
void PointerVariableConstraint::constrainToWild(Constraints &CS) const {
979-
ConstAtom *WA = CS.getWild();
980-
for (const auto &V : vars) {
981-
if (VarAtom *VA = dyn_cast<VarAtom>(V))
982-
CS.addConstraint(CS.createGeq(VA, WA, true));
983-
}
984-
985-
if (FV)
986-
FV->constrainToWild(CS);
968+
void PointerVariableConstraint::constrainToWild(Constraints &CS,
969+
const std::string &Rsn) const {
970+
constrainToWild(CS, Rsn, nullptr);
987971
}
988972

989973
void PointerVariableConstraint::constrainToWild(Constraints &CS,
990974
const std::string &Rsn,
991975
PersistentSourceLoc *PL) const {
992-
ConstAtom *WA = CS.getWild();
993-
for (const auto &V : vars) {
994-
if (VarAtom *VA = dyn_cast<VarAtom>(V))
995-
CS.addConstraint(CS.createGeq(VA, WA, Rsn, PL, true));
976+
// Constrains the outer pointer level to WILD. Inner pointer levels are
977+
// implicitly WILD because of implication constraints.
978+
if (!vars.empty()) {
979+
Atom *A = *vars.begin();
980+
if (auto *VA = dyn_cast<VarAtom>(A))
981+
CS.addConstraint(CS.createGeq(VA, CS.getWild(), Rsn, PL, true));
996982
}
997983

998984
if (FV)
999985
FV->constrainToWild(CS, Rsn, PL);
1000986
}
1001987

1002-
void PointerVariableConstraint::constrainToWild(Constraints &CS,
1003-
const std::string &Rsn) const {
1004-
ConstAtom *WA = CS.getWild();
1005-
for (const auto &V : vars) {
1006-
if (VarAtom *VA = dyn_cast<VarAtom>(V))
1007-
CS.addConstraint(CS.createGeq(VA, WA, Rsn, true));
1008-
}
1009-
1010-
if (FV)
1011-
FV->constrainToWild(CS, Rsn);
1012-
}
1013988

1014989
void PointerVariableConstraint::constrainOuterTo(Constraints &CS, ConstAtom *C,
1015990
bool doLB) {

clang/lib/CConv/DeclRewriter.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void DeclRewriter::rewriteMultiDecl(DeclReplacement *N, RSet &ToRewrite) {
227227
// original decl was re-written, write that out instead. Existing
228228
// initializers are preserved, any declarations that an initializer to
229229
// be valid checked-c are given one.
230-
std::set<Decl *> SameLineDecls;
230+
std::vector<Decl *> SameLineDecls;
231231
getDeclsOnSameLine(N, SameLineDecls);
232232

233233
bool IsFirst = true;
@@ -408,7 +408,7 @@ bool DeclRewriter::areDeclarationsOnSameLine(DeclReplacement *N1,
408408
DeclStmt *Stmt2 = N2->getStatement();
409409
if (Stmt1 == nullptr && Stmt2 == nullptr) {
410410
auto &DGroup = GP.getVarsOnSameLine(D1);
411-
return DGroup.find(D2) != DGroup.end();
411+
return llvm::is_contained(DGroup, D2);
412412
} else if (Stmt1 == nullptr || Stmt2 == nullptr) {
413413
return false;
414414
} else {
@@ -430,13 +430,20 @@ bool DeclRewriter::isSingleDeclaration(DeclReplacement *N) {
430430
}
431431

432432
void DeclRewriter::getDeclsOnSameLine(DeclReplacement *N,
433-
std::set<Decl *> &Decls) {
434-
if (N->getStatement() != nullptr)
435-
Decls.insert(N->getStatement()->decls().begin(),
433+
std::vector<Decl *> &Decls) {
434+
if (N->getStatement() != nullptr) {
435+
Decls.insert(Decls.begin(), N->getStatement()->decls().begin(),
436436
N->getStatement()->decls().end());
437-
else
438-
Decls.insert(GP.getVarsOnSameLine(N->getDecl()).begin(),
439-
GP.getVarsOnSameLine(N->getDecl()).end());
437+
} else {
438+
std::vector<Decl *> GlobalLine = GP.getVarsOnSameLine(N->getDecl());
439+
Decls.insert(Decls.begin(), GlobalLine.begin(), GlobalLine.end());
440+
}
441+
442+
assert("Invalid ordering in same line decls" &&
443+
std::is_sorted(Decls.begin(), Decls.end(), [&](Decl *D0, Decl *D1) {
444+
return A.getSourceManager().isBeforeInTranslationUnit(D0->getEndLoc(),
445+
D1->getEndLoc());
446+
}));
440447
}
441448

442449
// Note: This is variable declared static in the header file in order to pass

clang/lib/CConv/RewriteUtils.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,30 +88,33 @@ bool DComp::operator()(DeclReplacement *Lhs,
8888
return SM.isBeforeInTranslationUnit(X2, Y1);
8989
}
9090

91-
void GlobalVariableGroups::addGlobalDecl(Decl *VD, std::set<Decl *> *VDSet) {
91+
void GlobalVariableGroups::addGlobalDecl(Decl *VD, std::vector<Decl *> *VDVec) {
9292
if (VD && GlobVarGroups.find(VD) == GlobVarGroups.end()) {
93-
if (VDSet == nullptr)
94-
VDSet = new std::set<Decl *>();
95-
VDSet->insert(VD);
96-
GlobVarGroups[VD] = VDSet;
93+
if (VDVec == nullptr)
94+
VDVec = new std::vector<Decl *>();
95+
assert("Decls in group are not ordered correctly." && (VDVec->empty() ||
96+
SM.isBeforeInTranslationUnit(VDVec->back()->getEndLoc(),
97+
VD->getEndLoc())));
98+
VDVec->push_back(VD);
99+
GlobVarGroups[VD] = VDVec;
97100
// Process the next decl.
98101
Decl *NDecl = VD->getNextDeclInContext();
99102
if (isa_and_nonnull<VarDecl>(NDecl) || isa_and_nonnull<FieldDecl>(NDecl))
100103
if (VD->getBeginLoc() == NDecl->getBeginLoc())
101-
addGlobalDecl(dyn_cast<Decl>(NDecl), VDSet);
104+
addGlobalDecl(dyn_cast<Decl>(NDecl), VDVec);
102105
}
103106
}
104107

105108

106-
std::set<Decl *> &GlobalVariableGroups::getVarsOnSameLine(Decl *D) {
109+
std::vector<Decl *> &GlobalVariableGroups::getVarsOnSameLine(Decl *D) {
107110
assert (GlobVarGroups.find(D) != GlobVarGroups.end() &&
108111
"Expected to find the group.");
109112
return *(GlobVarGroups[D]);
110113
}
111114

112115

113116
GlobalVariableGroups::~GlobalVariableGroups() {
114-
std::set<std::set<Decl *> *> VVisited;
117+
std::set<std::vector<Decl *> *> VVisited;
115118
// Free each of the group.
116119
for (auto &currV : GlobVarGroups) {
117120
// Avoid double free by caching deleted sets.

0 commit comments

Comments
 (0)