Fixed bug that could case unwanted bifurcation of states when evaluating calls.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47964 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-03-05 21:15:02 +00:00
Родитель 1aa9a58822
Коммит 4bf38da038
3 изменённых файлов: 46 добавлений и 21 удалений

Просмотреть файл

@ -21,6 +21,18 @@
#include <sstream>
#endif
// SaveAndRestore - A utility class that uses RIIA to save and restore
// the value of a variable.
template<typename T>
struct VISIBILITY_HIDDEN SaveAndRestore {
SaveAndRestore(T& x) : X(x), old_value(x) {}
~SaveAndRestore() { X = old_value; }
T get() { return old_value; }
T& X;
T old_value;
};
using namespace clang;
using llvm::dyn_cast;
using llvm::cast;
@ -482,7 +494,27 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
}
continue;
}
}
// Check for the "noreturn" attribute.
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
if (isa<lval::FuncVal>(L))
if (cast<lval::FuncVal>(L).getDecl()->getAttr<NoReturnAttr>()) {
for (NodeSet::iterator I=Dst.begin(), E=Dst.end(); I != E; ++I ) {
NodeTy* N = *I;
if (!N->isSink())
N->markAsSink();
}
Builder->BuildSinks = true;
}
// Evaluate the call.
bool invalidateArgs = false;
@ -506,7 +538,9 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
if (isa<LVal>(V))
St = SetRVal(St, cast<LVal>(V), UnknownVal());
}
}
Nodify(Dst, CE, *DI, St);
}
else {
@ -542,23 +576,6 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
if (Dst.size() == size)
Nodify(Dst, CE, *DI, St);
}
// Check for the "noreturn" attribute.
if (isa<lval::FuncVal>(L))
if (cast<lval::FuncVal>(L).getDecl()->getAttr<NoReturnAttr>()) {
NodeTy* N = Builder->generateNode(CE, St, *DI);
if (N) {
N->markAsSink();
NoReturnCalls.insert(N);
}
continue;
}
Nodify(Dst, CE, *DI, St);
}
}

Просмотреть файл

@ -389,6 +389,8 @@ public:
inline unsigned size() const { return Impl.size(); }
inline bool empty() const { return Impl.empty(); }
inline void clear() { Impl.clear(); }
inline iterator begin() { return Impl.begin(); }
inline iterator end() { return Impl.end(); }

Просмотреть файл

@ -162,7 +162,7 @@ class GRStmtNodeBuilder {
GRStmtNodeBuilderImpl& NB;
public:
GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb) {}
GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb), BuildSinks(false) {}
NodeTy* getLastNode() const {
return static_cast<NodeTy*>(NB.getLastNode());
@ -186,10 +186,16 @@ public:
}
NodeTy* N = generateNode(S, St, Pred);
Dst.Add(N);
if (N && BuildSinks)
N->markAsSink();
else
Dst.Add(N);
return N;
}
bool BuildSinks;
};
class GRBranchNodeBuilderImpl {