mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 01:58:21 +00:00
Consumed Analysis: IgnoreParens bugfix.
llvm-svn: 204395
This commit is contained in:
parent
ba5570221d
commit
d7fa5bd431
@ -471,11 +471,21 @@ class ConsumedStmtVisitor : public ConstStmtVisitor<ConsumedStmtVisitor> {
|
||||
ConsumedStateMap *StateMap;
|
||||
MapType PropagationMap;
|
||||
|
||||
void forwardInfo(const Stmt *From, const Stmt *To);
|
||||
void copyInfo(const Stmt *From, const Stmt *To, ConsumedState CS);
|
||||
ConsumedState getInfo(const Stmt *From);
|
||||
void setInfo(const Stmt *To, ConsumedState NS);
|
||||
void propagateReturnType(const Stmt *Call, const FunctionDecl *Fun);
|
||||
InfoEntry findInfo(const Expr *E) {
|
||||
return PropagationMap.find(E->IgnoreParens());
|
||||
}
|
||||
ConstInfoEntry findInfo(const Expr *E) const {
|
||||
return PropagationMap.find(E->IgnoreParens());
|
||||
}
|
||||
void insertInfo(const Expr *E, const PropagationInfo &PI) {
|
||||
PropagationMap.insert(PairType(E->IgnoreParens(), PI));
|
||||
}
|
||||
|
||||
void forwardInfo(const Expr *From, const Expr *To);
|
||||
void copyInfo(const Expr *From, const Expr *To, ConsumedState CS);
|
||||
ConsumedState getInfo(const Expr *From);
|
||||
void setInfo(const Expr *To, ConsumedState NS);
|
||||
void propagateReturnType(const Expr *Call, const FunctionDecl *Fun);
|
||||
|
||||
public:
|
||||
void checkCallability(const PropagationInfo &PInfo,
|
||||
@ -504,8 +514,8 @@ public:
|
||||
ConsumedStateMap *StateMap)
|
||||
: AC(AC), Analyzer(Analyzer), StateMap(StateMap) {}
|
||||
|
||||
PropagationInfo getInfo(const Stmt *StmtNode) const {
|
||||
ConstInfoEntry Entry = PropagationMap.find(StmtNode);
|
||||
PropagationInfo getInfo(const Expr *StmtNode) const {
|
||||
ConstInfoEntry Entry = findInfo(StmtNode);
|
||||
|
||||
if (Entry != PropagationMap.end())
|
||||
return Entry->second;
|
||||
@ -519,23 +529,23 @@ public:
|
||||
};
|
||||
|
||||
|
||||
void ConsumedStmtVisitor::forwardInfo(const Stmt *From, const Stmt *To) {
|
||||
InfoEntry Entry = PropagationMap.find(From);
|
||||
void ConsumedStmtVisitor::forwardInfo(const Expr *From, const Expr *To) {
|
||||
InfoEntry Entry = findInfo(From);
|
||||
if (Entry != PropagationMap.end())
|
||||
PropagationMap.insert(PairType(To, Entry->second));
|
||||
insertInfo(To, Entry->second);
|
||||
}
|
||||
|
||||
|
||||
// Create a new state for To, which is initialized to the state of From.
|
||||
// If NS is not CS_None, sets the state of From to NS.
|
||||
void ConsumedStmtVisitor::copyInfo(const Stmt *From, const Stmt *To,
|
||||
void ConsumedStmtVisitor::copyInfo(const Expr *From, const Expr *To,
|
||||
ConsumedState NS) {
|
||||
InfoEntry Entry = PropagationMap.find(From);
|
||||
InfoEntry Entry = findInfo(From);
|
||||
if (Entry != PropagationMap.end()) {
|
||||
PropagationInfo& PInfo = Entry->second;
|
||||
ConsumedState CS = PInfo.getAsState(StateMap);
|
||||
if (CS != CS_None)
|
||||
PropagationMap.insert(PairType(To, CS));
|
||||
insertInfo(To, PropagationInfo(CS));
|
||||
if (NS != CS_None && PInfo.isPointerToValue())
|
||||
setStateForVarOrTmp(StateMap, PInfo, NS);
|
||||
}
|
||||
@ -543,8 +553,8 @@ void ConsumedStmtVisitor::copyInfo(const Stmt *From, const Stmt *To,
|
||||
|
||||
|
||||
// Get the ConsumedState for From
|
||||
ConsumedState ConsumedStmtVisitor::getInfo(const Stmt *From) {
|
||||
InfoEntry Entry = PropagationMap.find(From);
|
||||
ConsumedState ConsumedStmtVisitor::getInfo(const Expr *From) {
|
||||
InfoEntry Entry = findInfo(From);
|
||||
if (Entry != PropagationMap.end()) {
|
||||
PropagationInfo& PInfo = Entry->second;
|
||||
return PInfo.getAsState(StateMap);
|
||||
@ -554,14 +564,14 @@ ConsumedState ConsumedStmtVisitor::getInfo(const Stmt *From) {
|
||||
|
||||
|
||||
// If we already have info for To then update it, otherwise create a new entry.
|
||||
void ConsumedStmtVisitor::setInfo(const Stmt *To, ConsumedState NS) {
|
||||
InfoEntry Entry = PropagationMap.find(To);
|
||||
void ConsumedStmtVisitor::setInfo(const Expr *To, ConsumedState NS) {
|
||||
InfoEntry Entry = findInfo(To);
|
||||
if (Entry != PropagationMap.end()) {
|
||||
PropagationInfo& PInfo = Entry->second;
|
||||
if (PInfo.isPointerToValue())
|
||||
setStateForVarOrTmp(StateMap, PInfo, NS);
|
||||
} else if (NS != CS_None) {
|
||||
PropagationMap.insert(PairType(To, PropagationInfo(NS)));
|
||||
insertInfo(To, PropagationInfo(NS));
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,7 +626,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
|
||||
const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset);
|
||||
QualType ParamType = Param->getType();
|
||||
|
||||
InfoEntry Entry = PropagationMap.find(Call->getArg(Index));
|
||||
InfoEntry Entry = findInfo(Call->getArg(Index));
|
||||
|
||||
if (Entry == PropagationMap.end() || Entry->second.isTest())
|
||||
continue;
|
||||
@ -651,7 +661,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
|
||||
return false;
|
||||
|
||||
// check implicit 'self' parameter, if present
|
||||
InfoEntry Entry = PropagationMap.find(ObjArg);
|
||||
InfoEntry Entry = findInfo(ObjArg);
|
||||
if (Entry != PropagationMap.end()) {
|
||||
PropagationInfo PInfo = Entry->second;
|
||||
checkCallability(PInfo, FunD, Call->getExprLoc());
|
||||
@ -675,7 +685,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
|
||||
}
|
||||
|
||||
|
||||
void ConsumedStmtVisitor::propagateReturnType(const Stmt *Call,
|
||||
void ConsumedStmtVisitor::propagateReturnType(const Expr *Call,
|
||||
const FunctionDecl *Fun) {
|
||||
QualType RetType = Fun->getCallResultType();
|
||||
if (RetType->isReferenceType())
|
||||
@ -697,8 +707,8 @@ void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) {
|
||||
switch (BinOp->getOpcode()) {
|
||||
case BO_LAnd:
|
||||
case BO_LOr : {
|
||||
InfoEntry LEntry = PropagationMap.find(BinOp->getLHS()),
|
||||
REntry = PropagationMap.find(BinOp->getRHS());
|
||||
InfoEntry LEntry = findInfo(BinOp->getLHS()),
|
||||
REntry = findInfo(BinOp->getRHS());
|
||||
|
||||
VarTestResult LTest, RTest;
|
||||
|
||||
@ -770,7 +780,7 @@ void ConsumedStmtVisitor::VisitCastExpr(const CastExpr *Cast) {
|
||||
void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr(
|
||||
const CXXBindTemporaryExpr *Temp) {
|
||||
|
||||
InfoEntry Entry = PropagationMap.find(Temp->getSubExpr());
|
||||
InfoEntry Entry = findInfo(Temp->getSubExpr());
|
||||
|
||||
if (Entry != PropagationMap.end() && !Entry->second.isTest()) {
|
||||
StateMap->setState(Temp, Entry->second.getAsState(StateMap));
|
||||
@ -894,7 +904,7 @@ void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) {
|
||||
ConsumedState ExpectedState = Analyzer.getExpectedReturnState();
|
||||
|
||||
if (ExpectedState != CS_None) {
|
||||
InfoEntry Entry = PropagationMap.find(Ret->getRetValue());
|
||||
InfoEntry Entry = findInfo(Ret->getRetValue());
|
||||
|
||||
if (Entry != PropagationMap.end()) {
|
||||
ConsumedState RetState = Entry->second.getAsState(StateMap);
|
||||
@ -911,7 +921,7 @@ void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) {
|
||||
}
|
||||
|
||||
void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) {
|
||||
InfoEntry Entry = PropagationMap.find(UOp->getSubExpr()->IgnoreParens());
|
||||
InfoEntry Entry = findInfo(UOp->getSubExpr());
|
||||
if (Entry == PropagationMap.end()) return;
|
||||
|
||||
switch (UOp->getOpcode()) {
|
||||
@ -933,8 +943,7 @@ void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) {
|
||||
void ConsumedStmtVisitor::VisitVarDecl(const VarDecl *Var) {
|
||||
if (isConsumableType(Var->getType())) {
|
||||
if (Var->hasInit()) {
|
||||
MapType::iterator VIT = PropagationMap.find(
|
||||
Var->getInit()->IgnoreImplicit());
|
||||
MapType::iterator VIT = findInfo(Var->getInit()->IgnoreImplicit());
|
||||
if (VIT != PropagationMap.end()) {
|
||||
PropagationInfo PInfo = VIT->second;
|
||||
ConsumedState St = PInfo.getAsState(StateMap);
|
||||
@ -1292,7 +1301,7 @@ bool ConsumedAnalyzer::splitState(const CFGBlock *CurrBlock,
|
||||
if (const IfStmt *IfNode =
|
||||
dyn_cast_or_null<IfStmt>(CurrBlock->getTerminator().getStmt())) {
|
||||
|
||||
const Stmt *Cond = IfNode->getCond();
|
||||
const Expr *Cond = IfNode->getCond();
|
||||
|
||||
PInfo = Visitor.getInfo(Cond);
|
||||
if (!PInfo.isValid() && isa<BinaryOperator>(Cond))
|
||||
|
@ -684,6 +684,8 @@ class CONSUMABLE(unconsumed)
|
||||
int code;
|
||||
|
||||
public:
|
||||
static Status OK;
|
||||
|
||||
Status() RETURN_TYPESTATE(consumed);
|
||||
Status(int c) RETURN_TYPESTATE(unconsumed);
|
||||
|
||||
@ -693,6 +695,8 @@ public:
|
||||
Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
|
||||
Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
|
||||
|
||||
bool operator==(const Status &other) const SET_TYPESTATE(consumed);
|
||||
|
||||
bool check() const SET_TYPESTATE(consumed);
|
||||
void ignore() const SET_TYPESTATE(consumed);
|
||||
// Status& markAsChecked() { return *this; }
|
||||
@ -710,6 +714,11 @@ void handleStatusRef(Status& s);
|
||||
void handleStatusPtr(Status* s);
|
||||
void handleStatusUnmarked(const Status& s);
|
||||
|
||||
void log(const char* msg);
|
||||
void fail() __attribute__((noreturn));
|
||||
void checkStat(const Status& s);
|
||||
|
||||
|
||||
void testSimpleTemporaries0() {
|
||||
doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
|
||||
}
|
||||
@ -870,6 +879,29 @@ Status testReturnAutocast() {
|
||||
return s; // should autocast back to unconsumed
|
||||
}
|
||||
|
||||
|
||||
namespace TestParens {
|
||||
|
||||
void test3() {
|
||||
checkStat((doSomething()));
|
||||
}
|
||||
|
||||
void test4() {
|
||||
Status s = (doSomething());
|
||||
s.check();
|
||||
}
|
||||
|
||||
void test5() {
|
||||
(doSomething()).check();
|
||||
}
|
||||
|
||||
void test6() {
|
||||
if ((doSomething()) == Status::OK)
|
||||
return;
|
||||
}
|
||||
|
||||
} // end namespace TestParens
|
||||
|
||||
} // end namespace InitializerAssertionFailTest
|
||||
|
||||
|
||||
@ -899,3 +931,4 @@ namespace PR18260 {
|
||||
std::__1::move(x);
|
||||
}
|
||||
} // end namespace PR18260
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user