[cfe-commits] r47774 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/GRSimpleVals.cpp include/clang/Analysis/PathSensitive/GRExprEngine.h
Ted Kremenek
kremenek at apple.com
Fri Feb 29 15:14:48 PST 2008
Author: kremenek
Date: Fri Feb 29 17:14:48 2008
New Revision: 47774
URL: http://llvm.org/viewvc/llvm-project?rev=47774&view=rev
Log:
Add checks for function calls via a function pointer that is NULL, Undefined,
or otherwise a constant integer value that doesn't evaluate to an address.
Modified:
cfe/trunk/Analysis/GRExprEngine.cpp
cfe/trunk/Analysis/GRSimpleVals.cpp
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
Modified: cfe/trunk/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRExprEngine.cpp?rev=47774&r1=47773&r2=47774&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Fri Feb 29 17:14:48 2008
@@ -507,11 +507,10 @@
// Check for undefined control-flow.
- if (L.isUndef()) {
-
+ if (L.isUndef() || isa<lval::ConcreteInt>(L)) {
NodeTy* N = Builder->generateNode(CE, St, *DI);
N->markAsSink();
- UndefBranches.insert(N);
+ BadCalls.insert(N);
continue;
}
@@ -1591,7 +1590,8 @@
GraphPrintCheckerState->isUndefStore(N) ||
GraphPrintCheckerState->isUndefControlFlow(N) ||
GraphPrintCheckerState->isBadDivide(N) ||
- GraphPrintCheckerState->isUndefResult(N))
+ GraphPrintCheckerState->isUndefResult(N) ||
+ GraphPrintCheckerState->isBadCall(N))
return "color=\"red\",style=\"filled\"";
if (GraphPrintCheckerState->isNoReturnCall(N))
@@ -1623,26 +1623,22 @@
L.getStmt()->printPretty(Out);
- if (GraphPrintCheckerState->isImplicitNullDeref(N)) {
+ if (GraphPrintCheckerState->isImplicitNullDeref(N))
Out << "\\|Implicit-Null Dereference.\\l";
- }
- else if (GraphPrintCheckerState->isExplicitNullDeref(N)) {
+ else if (GraphPrintCheckerState->isExplicitNullDeref(N))
Out << "\\|Explicit-Null Dereference.\\l";
- }
- else if (GraphPrintCheckerState->isUndefDeref(N)) {
+ else if (GraphPrintCheckerState->isUndefDeref(N))
Out << "\\|Dereference of undefialied value.\\l";
- }
- else if (GraphPrintCheckerState->isUndefStore(N)) {
+ else if (GraphPrintCheckerState->isUndefStore(N))
Out << "\\|Store to Undefined LVal.";
- }
- else if (GraphPrintCheckerState->isBadDivide(N)) {
+ else if (GraphPrintCheckerState->isBadDivide(N))
Out << "\\|Divide-by zero or undefined value.";
- }
- else if (GraphPrintCheckerState->isUndefResult(N)) {
+ else if (GraphPrintCheckerState->isUndefResult(N))
Out << "\\|Result of operation is undefined.";
- }
else if (GraphPrintCheckerState->isNoReturnCall(N))
Out << "\\|Call to function marked \"noreturn\".";
+ else if (GraphPrintCheckerState->isBadCall(N))
+ Out << "\\|Call to NULL/Undefined.";
break;
}
Modified: cfe/trunk/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.cpp?rev=47774&r1=47773&r2=47774&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Fri Feb 29 17:14:48 2008
@@ -101,6 +101,11 @@
CheckerState->undef_results_begin(),
CheckerState->undef_results_end(),
"Result of operation is undefined.");
+
+ EmitWarning(Diag, SrcMgr,
+ CheckerState->bad_calls_begin(),
+ CheckerState->bad_calls_end(),
+ "Call using a NULL or undefined function pointer value.");
#ifndef NDEBUG
if (Visualize) CheckerState->ViewGraph();
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=47774&r1=47773&r2=47774&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Feb 29 17:14:48 2008
@@ -90,6 +90,7 @@
typedef llvm::SmallPtrSet<NodeTy*,2> UndefBranchesTy;
typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy;
typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy;
+ typedef llvm::SmallPtrSet<NodeTy*,2> BadCallsTy;
typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy;
typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;
typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;
@@ -127,6 +128,10 @@
/// by the result is not. Excludes divide-by-zero errors.
UndefResultsTy UndefResults;
+ /// BadCalls - Nodes in the ExplodedGraph resulting from calls to function
+ /// pointers that are NULL (or other constants) or Undefined.
+ BadCallsTy BadCalls;
+
bool StateCleaned;
public:
@@ -194,6 +199,10 @@
return N->isSink() && UndefResults.count(const_cast<NodeTy*>(N)) != 0;
}
+ bool isBadCall(const NodeTy* N) const {
+ return N->isSink() && BadCalls.count(const_cast<NodeTy*>(N)) != 0;
+ }
+
typedef BadDerefTy::iterator null_deref_iterator;
null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); }
null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); }
@@ -209,6 +218,10 @@
typedef UndefResultsTy::iterator undef_result_iterator;
undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
undef_result_iterator undef_results_end() { return UndefResults.end(); }
+
+ typedef BadCallsTy::iterator bad_calls_iterator;
+ bad_calls_iterator bad_calls_begin() { return BadCalls.begin(); }
+ bad_calls_iterator bad_calls_end() { return BadCalls.end(); }
/// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement.
More information about the cfe-commits
mailing list