Skip to content

Commit 2a96dfb

Browse files
authored
Adding bounds inference of the form count(i+1) (#602)
* Adding bounds inferrence of the form count(i+1) * Fixing Review comments * Fixing issue where the declaration has only types
1 parent b75d0a3 commit 2a96dfb

19 files changed

+295
-155
lines changed

clang/include/clang/3C/ABounds.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ class ABounds {
2828
InvalidKind,
2929
// Bounds that represent number of items.
3030
CountBoundKind,
31+
// Count bounds but plus one, i.e., count(i+1)
32+
CountPlusOneBoundKind,
3133
// Bounds that represent number of bytes.
3234
ByteBoundKind,
3335
// Bounds that represent range.
3436
RangeBoundKind,
3537
};
3638
BoundsKind getKind() const { return Kind; }
3739

38-
private:
40+
protected:
3941
BoundsKind Kind;
4042

4143
protected:
@@ -83,10 +85,24 @@ class CountBound : public ABounds {
8385

8486
BoundsKey getCountVar() { return CountVar; }
8587

86-
private:
88+
protected:
8789
BoundsKey CountVar;
8890
};
8991

92+
class CountPlusOneBound : public CountBound {
93+
public:
94+
CountPlusOneBound(BoundsKey Var) : CountBound(Var) {
95+
this->Kind = CountPlusOneBoundKind;
96+
}
97+
98+
std::string mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr) override;
99+
bool areSame(ABounds *O, AVarBoundsInfo *ABI) override;
100+
101+
static bool classof(const ABounds *S) {
102+
return S->getKind() == CountPlusOneBoundKind;
103+
}
104+
};
105+
90106
class ByteBound : public ABounds {
91107
public:
92108
ByteBound(BoundsKey Var) : ABounds(ByteBoundKind), ByteVar(Var) {

clang/include/clang/3C/AVarBoundsInfo.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ class AvarBoundsInference {
138138
bool hasImpossibleBounds(BoundsKey BK);
139139
// Set the given pointer to have impossible bounds.
140140
void setImpossibleBounds(BoundsKey BK);
141+
// Infer bounds of the given pointer key from potential bounds.
142+
bool inferFromPotentialBounds(BoundsKey BK, AVarGraph &BKGraph);
141143

142144
AVarBoundsInfo *BI;
143145

@@ -147,6 +149,31 @@ class AvarBoundsInference {
147149
std::set<BoundsKey> BKsFailedFlowInference;
148150
};
149151

152+
// Class that maintains information about potential bounds for
153+
// various pointer variables.
154+
class PotentialBoundsInfo {
155+
public:
156+
PotentialBoundsInfo() {
157+
PotentialCntBounds.clear();
158+
PotentialCntPOneBounds.clear();
159+
}
160+
// Count Bounds, i.e., count(i).
161+
bool hasPotentialCountBounds(BoundsKey PtrBK);
162+
std::set<BoundsKey> &getPotentialBounds(BoundsKey PtrBK);
163+
void addPotentialBounds(BoundsKey BK, const std::set<BoundsKey> &PotK);
164+
165+
// Count Bounds Plus one, i.e., count(i+1).
166+
bool hasPotentialCountPOneBounds(BoundsKey PtrBK);
167+
std::set<BoundsKey> &getPotentialBoundsPOne(BoundsKey PtrBK);
168+
void addPotentialBoundsPOne(BoundsKey BK, const std::set<BoundsKey> &PotK);
169+
private:
170+
// This is the map of pointer variable bounds key and set of bounds key
171+
// which can be the count bounds.
172+
std::map<BoundsKey, std::set<BoundsKey>> PotentialCntBounds;
173+
// Potential count + 1 bounds.
174+
std::map<BoundsKey, std::set<BoundsKey>> PotentialCntPOneBounds;
175+
};
176+
150177
class AVarBoundsInfo {
151178
public:
152179
AVarBoundsInfo() : ProgVarGraph(this), CtxSensProgVarGraph(this),
@@ -171,7 +198,10 @@ class AVarBoundsInfo {
171198
bool replaceBounds(BoundsKey L, BoundsPriority P, ABounds *B);
172199
ABounds *getBounds(BoundsKey L, BoundsPriority ReqP = Invalid,
173200
BoundsPriority *RetP = nullptr);
174-
bool updatePotentialCountBounds(BoundsKey BK, std::set<BoundsKey> &CntBK);
201+
void updatePotentialCountBounds(BoundsKey BK,
202+
const std::set<BoundsKey> &CntBK);
203+
void updatePotentialCountPOneBounds(BoundsKey BK,
204+
const std::set<BoundsKey> &CntBK);
175205

176206
// Try and get BoundsKey, into R, for the given declaration. If the
177207
// declaration does not have a BoundsKey then return false.
@@ -316,9 +346,8 @@ class AVarBoundsInfo {
316346
AVarGraph RevCtxSensProgVarGraph;
317347
// Stats on techniques used to find length for various variables.
318348
AVarBoundsStats BoundsInferStats;
319-
// This is the map of pointer variable bounds key and set of bounds key
320-
// which can be the count bounds.
321-
std::map<BoundsKey, std::set<BoundsKey>> PotentialCntBounds;
349+
// Information about potential bounds.
350+
PotentialBoundsInfo PotBoundsInfo;
322351
// Context-sensitive bounds key handler
323352
CtxSensitiveBoundsKeyHandler CSBKeyHandler;
324353

@@ -351,7 +380,8 @@ class AVarBoundsInfo {
351380
// Perform worklist based inference on the requested array variables using
352381
// the provided graph and potential length variables.
353382
bool performWorkListInference(const std::set<BoundsKey> &ArrNeededBounds,
354-
AVarGraph &BKGraph, AvarBoundsInference &BI);
383+
AVarGraph &BKGraph, AvarBoundsInference &BI,
384+
bool FromPB);
355385

356386
void insertParamKey(ParamDeclType ParamDecl, BoundsKey NK);
357387
};

clang/lib/3C/ABounds.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ std::string ABounds::getBoundsKeyStr(BoundsKey BK,
7272
if (FD->getNumParams() > PIdx) {
7373
auto *NewPVD = FD->getParamDecl(PIdx);
7474
BKStr = NewPVD->getNameAsString();
75+
// If the parameter in the new declaration does not have a name?
76+
// then use the old name.
77+
if (BKStr.empty())
78+
BKStr = PV->mkString();
7579
}
7680
}
7781
return BKStr;
@@ -93,16 +97,24 @@ BoundsKey CountBound::getBKey() { return this->CountVar; }
9397

9498
ABounds *CountBound::makeCopy(BoundsKey NK) { return new CountBound(NK); }
9599

100+
std::string CountPlusOneBound::mkString(AVarBoundsInfo *ABI, clang::Decl *D) {
101+
std::string CVar = ABounds::getBoundsKeyStr(CountVar, ABI, D);
102+
return "count(" + CVar + " + 1)";
103+
}
104+
105+
bool CountPlusOneBound::areSame(ABounds *O, AVarBoundsInfo *ABI) {
106+
if (CountPlusOneBound *OT = dyn_cast_or_null<CountPlusOneBound>(O))
107+
return ABI->areSameProgramVar(this->CountVar, OT->CountVar);
108+
return false;
109+
}
110+
96111
std::string ByteBound::mkString(AVarBoundsInfo *ABI, clang::Decl *D) {
97112
return "byte_count(" + ABounds::getBoundsKeyStr(ByteVar, ABI, D) + ")";
98113
}
99114

100115
bool ByteBound::areSame(ABounds *O, AVarBoundsInfo *ABI) {
101-
if (O != nullptr) {
102-
if (ByteBound *BB = dyn_cast<ByteBound>(O)) {
103-
return ABI->areSameProgramVar(this->ByteVar, BB->ByteVar);
104-
}
105-
}
116+
if (ByteBound *BB = dyn_cast_or_null<ByteBound>(O))
117+
return ABI->areSameProgramVar(this->ByteVar, BB->ByteVar);
106118
return false;
107119
}
108120

@@ -118,11 +130,8 @@ std::string RangeBound::mkString(AVarBoundsInfo *ABI, clang::Decl *D) {
118130
}
119131

120132
bool RangeBound::areSame(ABounds *O, AVarBoundsInfo *ABI) {
121-
if (O != nullptr) {
122-
if (RangeBound *RB = dyn_cast<RangeBound>(O)) {
123-
return ABI->areSameProgramVar(this->LB, RB->LB) &&
124-
ABI->areSameProgramVar(this->UB, RB->UB);
125-
}
126-
}
133+
if (RangeBound *RB = dyn_cast_or_null<RangeBound>(O))
134+
return ABI->areSameProgramVar(this->LB, RB->LB) &&
135+
ABI->areSameProgramVar(this->UB, RB->UB);
127136
return false;
128137
}

0 commit comments

Comments
 (0)