Skip to content

Commit 14fab9c

Browse files
committed
Changes
fix bug of handling loop like while (true) fix bug of finding best cover for switch define and use debug macros Signed-off-by: cppbear <[email protected]>
1 parent 09c088d commit 14fab9c

File tree

11 files changed

+164
-318
lines changed

11 files changed

+164
-318
lines changed

clang-tools-extra/brinfo/Analysis.cpp

Lines changed: 36 additions & 287 deletions
Large diffs are not rendered by default.

clang-tools-extra/brinfo/Analysis.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include "CondChain.h"
24
#include <unordered_set>
35

@@ -12,6 +14,7 @@ struct BlkCond {
1214
const CFGBlock *Block = nullptr;
1315
BaseCond *Condition = nullptr;
1416
bool Flag = false;
17+
bool InLoop = false;
1518
};
1619

1720
class Analysis {
@@ -27,26 +30,22 @@ class Analysis {
2730
json Results;
2831
unordered_set<string> VisitedFuncs;
2932

30-
// vector<CondChainList> BlkChain;
3133
CondChainList CondChainForBlk;
3234
CondChainList CondChains;
3335
vector<unsigned char> ColorOfBlk;
34-
// long Parent;
35-
// bool DeathLoop = false;
3636

3737
unordered_map<unsigned, unordered_set<unsigned>> LoopInner;
3838

3939
void setSignature();
4040
void extractCondChains();
41-
long findBestCover(set<pair<const Stmt *, bool>> &Uncovered,
41+
long findBestCover(set<tuple<const Stmt *, string, bool>> &Uncovered,
4242
const CondChainList &CondChains, vector<bool> &Used);
4343
unordered_set<unsigned> findMinCover();
4444
void condChainsToReqs();
4545
void clear();
4646

4747
void toBlack();
4848
void dfsTraverseCFGLoop(long Parent, CFGBlock *FirstBlk);
49-
// void dfsTraverseCFG(CFGBlock *Blk, BaseCond *Condition, bool Flag);
5049
void dumpCondChains();
5150
void dumpBlkChain(unsigned ID);
5251
void dumpBlkChain();

clang-tools-extra/brinfo/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ clang_target_link_libraries(brinfo
1919
nlohmann_json::nlohmann_json
2020
)
2121

22+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
23+
target_compile_definitions(brinfo PRIVATE DEBUG)
24+
endif()
25+
2226
install(TARGETS brinfo
2327
RUNTIME DESTINATION bin
2428
COMPONENT brinfo)

clang-tools-extra/brinfo/CondChain.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -210,26 +210,26 @@ StringList CondStatus::getLastDefStrVec(ASTContext *Context) {
210210
void CondStatus::dump(ASTContext *Context) {
211211
if (Condition) {
212212
Condition->dump(Context);
213-
errs() << " is " << (Flag ? "true" : "false");
213+
outs() << " is " << (Flag ? "true" : "false");
214214
if (!LastDefStmts.empty() || !ParmVars.empty()) {
215215
string Str;
216216
raw_string_ostream OS(Str);
217-
errs() << ", where: ";
217+
outs() << ", where: ";
218218
unsigned I = 0;
219219
for (const Stmt *S : LastDefStmts) {
220220
S->printPretty(OS, nullptr, Context->getPrintingPolicy());
221221
OS.flush();
222222
rtrim(Str);
223223
if (I++ > 0)
224-
errs() << ", ";
225-
errs() << Str;
224+
outs() << ", ";
225+
outs() << Str;
226226
Str.clear();
227227
}
228228
I = 0;
229229
for (const ParmVarDecl *PVD : ParmVars) {
230230
if (I++ > 0)
231-
errs() << ", ";
232-
errs() << PVD->getNameAsString() << " is ParmVar";
231+
outs() << ", ";
232+
outs() << PVD->getNameAsString() << " is ParmVar";
233233
}
234234
}
235235
}
@@ -626,24 +626,24 @@ void CondChainInfo::dumpFuncCallInfo() {
626626

627627
void CondChainInfo::dump(ASTContext *Context, unsigned Indent) {
628628
string IndentStr(Indent, ' ');
629-
errs() << IndentStr;
629+
outs() << IndentStr;
630630
unsigned CondNum = Chain.size();
631631
unsigned I = 0;
632632
for (unsigned J = 0; J < CondNum; ++J) {
633633
if (Chain[J].Condition) {
634634
if (I++ > 0)
635-
errs() << " \033[36m\033[1m->\033[0m ";
635+
outs() << " \033[36m\033[1m->\033[0m ";
636636
Chain[J].dump(Context);
637637
}
638638
}
639-
errs() << "\n" + IndentStr;
639+
outs() << "\n" + IndentStr;
640640
I = 0;
641641
for (const CFGBlock *Blk : Path) {
642642
if (I++ > 0)
643-
errs() << " \033[36m\033[1m->\033[0m ";
644-
errs() << Blk->getBlockID();
643+
outs() << " \033[36m\033[1m->\033[0m ";
644+
outs() << Blk->getBlockID();
645645
}
646-
errs() << "\n";
646+
outs() << "\n";
647647
}
648648

649649
json CondChainInfo::toTestReqs(ASTContext *Context) {
@@ -739,14 +739,14 @@ string CondChainInfo::getReturnStr(ASTContext *Context, string ReturnType) {
739739
return Result;
740740
}
741741

742-
set<pair<const Stmt *, bool>> CondChainInfo::getCondSet() const {
743-
set<pair<const Stmt *, bool>> Set;
742+
set<tuple<const Stmt *, string, bool>> CondChainInfo::getCondSet() const {
743+
set<tuple<const Stmt *, string, bool>> Set;
744744
for (CondStatus Cond : Chain) {
745745
if (Cond.Condition) {
746746
bool Flag = Cond.Flag;
747747
// if (Cond.Condition->isNot())
748748
// Flag = !Flag;
749-
Set.insert({Cond.Condition->getCond(), Flag});
749+
Set.insert({Cond.Condition->getCond(), Cond.Condition->getCondStr(), Flag});
750750
}
751751
}
752752
return Set;

clang-tools-extra/brinfo/CondChain.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include "Condition.h"
24
#include "nlohmann/json.hpp"
35
#include <set>
@@ -95,7 +97,7 @@ struct CondChainInfo {
9597
json toTestReqs(ASTContext *Context);
9698
string getReturnStr(ASTContext *Context, string ReturnType);
9799

98-
set<pair<const Stmt *, bool>> getCondSet() const;
100+
set<tuple<const Stmt *, string, bool>> getCondSet() const;
99101
};
100102

101103
struct CondSimp {

clang-tools-extra/brinfo/Condition.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,34 @@ string LoopCond::toString(const ASTContext *Context) {
116116
return OS.str();
117117
}
118118

119+
void CaseCond::setCondStr(const ASTContext *Context) {
120+
if (!CondStr.empty())
121+
return;
122+
llvm::raw_string_ostream OS(CondStr);
123+
if (Cond->getStmtClass() == Stmt::BinaryOperatorClass &&
124+
cast<BinaryOperator>(Cond)->getOpcode() == BinaryOperatorKind::BO_NE) {
125+
IsNot = true;
126+
Expr *LHS = cast<BinaryOperator>(Cond)->getLHS()->IgnoreParenImpCasts();
127+
Expr *RHS = cast<BinaryOperator>(Cond)->getRHS()->IgnoreParenImpCasts();
128+
LHS->printPretty(OS, nullptr, Context->getPrintingPolicy());
129+
OS << " == ";
130+
RHS->printPretty(OS, nullptr, Context->getPrintingPolicy());
131+
} else if (Cond->getStmtClass() == Stmt::UnaryOperatorClass &&
132+
cast<UnaryOperator>(Cond)->getOpcode() ==
133+
UnaryOperatorKind::UO_LNot) {
134+
IsNot = true;
135+
Expr *SubExpr =
136+
cast<UnaryOperator>(Cond)->getSubExpr()->IgnoreParenImpCasts();
137+
SubExpr->printPretty(OS, nullptr, Context->getPrintingPolicy());
138+
} else {
139+
Cond->printPretty(OS, nullptr, Context->getPrintingPolicy());
140+
}
141+
rtrim(CondStr);
142+
OS << " == ";
143+
Case->printPretty(OS, nullptr, Context->getPrintingPolicy());
144+
rtrim(CondStr);
145+
}
146+
119147
void CaseCond::dump(const ASTContext *Context) {
120148
Cond->dumpPretty(*Context);
121149
outs() << ": ";
@@ -131,6 +159,41 @@ string CaseCond::toString(const ASTContext *Context) {
131159
return OS.str();
132160
}
133161

162+
void DefaultCond::setCondStr(const ASTContext *Context) {
163+
if (!CondStr.empty())
164+
return;
165+
llvm::raw_string_ostream OS(CondStr);
166+
if (Cond->getStmtClass() == Stmt::BinaryOperatorClass &&
167+
cast<BinaryOperator>(Cond)->getOpcode() == BinaryOperatorKind::BO_NE) {
168+
IsNot = true;
169+
Expr *LHS = cast<BinaryOperator>(Cond)->getLHS()->IgnoreParenImpCasts();
170+
Expr *RHS = cast<BinaryOperator>(Cond)->getRHS()->IgnoreParenImpCasts();
171+
LHS->printPretty(OS, nullptr, Context->getPrintingPolicy());
172+
OS << " == ";
173+
RHS->printPretty(OS, nullptr, Context->getPrintingPolicy());
174+
} else if (Cond->getStmtClass() == Stmt::UnaryOperatorClass &&
175+
cast<UnaryOperator>(Cond)->getOpcode() ==
176+
UnaryOperatorKind::UO_LNot) {
177+
IsNot = true;
178+
Expr *SubExpr =
179+
cast<UnaryOperator>(Cond)->getSubExpr()->IgnoreParenImpCasts();
180+
SubExpr->printPretty(OS, nullptr, Context->getPrintingPolicy());
181+
} else {
182+
Cond->printPretty(OS, nullptr, Context->getPrintingPolicy());
183+
}
184+
rtrim(CondStr);
185+
string SwitchValue = CondStr;
186+
unsigned I = 0;
187+
for (const Stmt *Case : Cases) {
188+
if (I++ > 0) {
189+
OS << " || " << SwitchValue;
190+
}
191+
OS << " == ";
192+
Case->printPretty(OS, nullptr, Context->getPrintingPolicy());
193+
}
194+
rtrim(CondStr);
195+
}
196+
134197
void DefaultCond::dump(const ASTContext *Context) {
135198
Cond->dumpPretty(*Context);
136199
outs() << ": ";

clang-tools-extra/brinfo/Condition.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include "clang/Analysis/CFG.h"
24

35
using namespace clang;
@@ -35,7 +37,6 @@ class BaseCond {
3537
BaseCond(CondKind K, const Stmt *Cond) : Kind(K), Cond(Cond) {
3638
findDeclRefExpr(Cond);
3739
findCallExpr(Cond);
38-
// setCondStr(Context);
3940
}
4041
virtual ~BaseCond() { Cond = nullptr; }
4142
CondKind getKind() const { return Kind; }
@@ -48,17 +49,15 @@ class BaseCond {
4849
bool containCallExpr() { return ContainCallExpr; }
4950
vector<const DeclRefExpr *> &getDeclRefExprList() { return DeclRefExprList; }
5051
vector<const CallExpr *> &getCallExprList() { return CallExprList; }
51-
void setCondStr(const ASTContext *Context);
52+
virtual void setCondStr(const ASTContext *Context);
5253
};
5354

5455
class IfCond : public BaseCond {
5556
public:
5657
IfCond(const Stmt *Cond) : BaseCond(IF, Cond) {
57-
// setCondStr(Context);
5858
}
5959
virtual ~IfCond() {}
6060
void dump(const ASTContext *Context) override;
61-
// void setCondStr(const ASTContext &Context);
6261
string toString(const ASTContext *Context) override;
6362
static bool classof(const BaseCond *Cond) { return Cond->getKind() == IF; }
6463
};
@@ -69,11 +68,10 @@ class CaseCond : public BaseCond {
6968
public:
7069
CaseCond(const Stmt *Cond, const Stmt *Case)
7170
: BaseCond(CASE, Cond), Case(Case) {
72-
// setCondStr(Context);
7371
}
7472
virtual ~CaseCond() { Case = nullptr; }
7573
void dump(const ASTContext *Context) override;
76-
void setCondStr(const ASTContext *Context){};
74+
void setCondStr(const ASTContext *Context) override;
7775
string toString(const ASTContext *Context) override;
7876
static bool classof(const BaseCond *Cond) { return Cond->getKind() == CASE; }
7977
};
@@ -84,11 +82,10 @@ class DefaultCond : public BaseCond {
8482
public:
8583
DefaultCond(const Stmt *Cond, vector<const Stmt *> Cases)
8684
: BaseCond(DEFAULT, Cond), Cases(Cases) {
87-
// setCondStr(Context);
8885
}
8986
virtual ~DefaultCond() {}
9087
void dump(const ASTContext *Context) override;
91-
void setCondStr(const ASTContext *Context){};
88+
void setCondStr(const ASTContext *Context) override;
9289
string toString(const ASTContext *Context) override;
9390
static bool classof(const BaseCond *Cond) {
9491
return Cond->getKind() == DEFAULT;
@@ -98,11 +95,9 @@ class DefaultCond : public BaseCond {
9895
class LoopCond : public BaseCond {
9996
public:
10097
LoopCond(const Stmt *Cond) : BaseCond(LOOP, Cond) {
101-
// setCondStr(Context);
10298
}
10399
virtual ~LoopCond() {}
104100
void dump(const ASTContext *Context) override;
105-
void setCondStr(const ASTContext *Context){};
106101
string toString(const ASTContext *Context) override;
107102
static bool classof(const BaseCond *Cond) { return Cond->getKind() == LOOP; }
108103
};

clang-tools-extra/brinfo/FrontedAction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include "Analysis.h"
24
#include "clang/AST/RecursiveASTVisitor.h"
35
#include "clang/Analysis/CFG.h"

clang-tools-extra/brinfo/Matcher.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include "Analysis.h"
24
#include "clang/ASTMatchers/ASTMatchFinder.h"
35
#include "clang/Tooling/Execution.h"

clang-tools-extra/brinfo/OrderedSet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
#include <unordered_set>
24
#include <vector>
35

0 commit comments

Comments
 (0)