[cfe-commits] r50112 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/GRExprEngine.cpp
Ted Kremenek
kremenek at apple.com
Tue Apr 22 15:25:28 PDT 2008
Author: kremenek
Date: Tue Apr 22 17:25:27 2008
New Revision: 50112
URL: http://llvm.org/viewvc/llvm-project?rev=50112&view=rev
Log:
Rewrote VisitDeclStmt to properly handle initializers that can do anything.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/lib/Analysis/GRExprEngine.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=50112&r1=50111&r2=50112&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Tue Apr 22 17:25:27 2008
@@ -521,6 +521,9 @@
/// VisitDeclStmt - Transfer function logic for DeclStmts.
void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
+ void VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
+ NodeTy* Pred, NodeSet& Dst);
+
void VisitDeref(UnaryOperator* U, NodeTy* Pred, NodeSet& Dst,
bool GetLVal = false);
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=50112&r1=50111&r2=50112&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Tue Apr 22 17:25:27 2008
@@ -1164,74 +1164,104 @@
}
}
-void GRExprEngine::VisitDeclStmt(DeclStmt* DS, GRExprEngine::NodeTy* Pred,
- GRExprEngine::NodeSet& Dst) {
+void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) {
+ VisitDeclStmtAux(DS, DS->getDecl(), Pred, Dst);
+}
+
+void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D,
+ NodeTy* Pred, NodeSet& Dst) {
+
+ if (!D)
+ return;
- ValueState* St = GetState(Pred);
+ if (!isa<VarDecl>(D)) {
+ VisitDeclStmtAux(DS, D->getNextDeclarator(), Pred, Dst);
+ return;
+ }
+
+ const VarDecl* VD = dyn_cast<VarDecl>(D);
+
+ // FIXME: Add support for local arrays.
+ if (VD->getType()->isArrayType()) {
+ VisitDeclStmtAux(DS, D->getNextDeclarator(), Pred, Dst);
+ return;
+ }
+
+ Expr* Ex = const_cast<Expr*>(VD->getInit());
+
+ // FIXME: static variables may have an initializer, but the second
+ // time a function is called those values may not be current.
+ NodeSet Tmp;
+
+ if (Ex) Visit(Ex, Pred, Tmp);
+ if (Tmp.empty()) Tmp.Add(Pred);
- for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
- if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
+ for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- // FIXME: Add support for local arrays.
- if (VD->getType()->isArrayType())
- continue;
+ ValueState* St = GetState(*I);
+
+ if (!Ex && VD->hasGlobalStorage()) {
- const Expr* Ex = VD->getInit();
+ // Handle variables with global storage and no initializers.
- if (!VD->hasGlobalStorage() || VD->getStorageClass() == VarDecl::Static) {
-
- // In this context, Static => Local variable.
-
- assert (!VD->getStorageClass() == VarDecl::Static ||
- !VD->isFileVarDecl());
+ // FIXME: static variables may have an initializer, but the second
+ // time a function is called those values may not be current.
+
+
+ // In this context, Static => Local variable.
+
+ assert (!VD->getStorageClass() == VarDecl::Static ||
+ !VD->isFileVarDecl());
+
+ // If there is no initializer, set the value of the
+ // variable to "Undefined".
+
+ if (VD->getStorageClass() == VarDecl::Static) {
+
+ // C99: 6.7.8 Initialization
+ // If an object that has static storage duration is not initialized
+ // explicitly, then:
+ // âif it has pointer type, it is initialized to a null pointer;
+ // âif it has arithmetic type, it is initialized to (positive or
+ // unsigned) zero;
- // If there is no initializer, set the value of the
- // variable to "Undefined".
- //
- // FIXME: static variables may have an initializer, but the second
- // time a function is called those values may not be current.
+ // FIXME: Handle structs. Now we treat their values as unknown.
QualType T = VD->getType();
- if ( VD->getStorageClass() == VarDecl::Static) {
-
- // C99: 6.7.8 Initialization
- // If an object that has static storage duration is not initialized
- // explicitly, then:
- // âif it has pointer type, it is initialized to a null pointer;
- // âif it has arithmetic type, it is initialized to (positive or
- // unsigned) zero;
-
- // FIXME: Handle structs. Now we treat their values as unknown.
-
- if (T->isPointerType()) {
-
- St = SetRVal(St, lval::DeclVal(VD),
- lval::ConcreteInt(BasicVals.getValue(0, T)));
- }
- else if (T->isIntegerType()) {
-
- St = SetRVal(St, lval::DeclVal(VD),
- nonlval::ConcreteInt(BasicVals.getValue(0, T)));
- }
+ if (T->isPointerType())
+ St = SetRVal(St, lval::DeclVal(VD),
+ lval::ConcreteInt(BasicVals.getValue(0, T)));
+ else if (T->isIntegerType())
+ St = SetRVal(St, lval::DeclVal(VD),
+ nonlval::ConcreteInt(BasicVals.getValue(0, T)));
-
- }
- else {
-
- // FIXME: Handle structs. Now we treat them as unknown. What
- // we need to do is treat their members as unknown.
-
- if (T->isPointerType() || T->isIntegerType())
- St = SetRVal(St, lval::DeclVal(VD),
- Ex ? GetRVal(St, Ex) : UndefinedVal());
- }
+ // FIXME: Handle structs. Now we treat them as unknown. What
+ // we need to do is treat their members as unknown.
}
}
+ else {
+
+ // FIXME: Handle structs. Now we treat them as unknown. What
+ // we need to do is treat their members as unknown.
- MakeNode(Dst, DS, Pred, St);
-}
+ QualType T = VD->getType();
+ if (T->isPointerType() || T->isIntegerType())
+ St = SetRVal(St, lval::DeclVal(VD),
+ Ex ? GetRVal(St, Ex) : UndefinedVal());
+ }
+
+ // Create a new node. We don't really need to create a new NodeSet
+ // here, but it simplifies things and doesn't cost much.
+ NodeSet Tmp2;
+ MakeNode(Tmp2, DS, *I, St);
+ if (Tmp2.empty()) Tmp2.Add(*I);
+
+ for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2)
+ VisitDeclStmtAux(DS, D->getNextDeclarator(), *I2, Dst);
+ }
+}
/// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type).
More information about the cfe-commits
mailing list