aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-02-20 20:27:11 +0000
committerChris Lattner <sabre@nondot.org>2004-02-20 20:27:11 +0000
commit8ecc27e66750077724539a02b5c20d8b942a8e50 (patch)
tree4a75c0a1b852a8b759a2d37c01df0f9d63eacd5d /lib/Analysis/DataStructure
parent3da125839d61e0bb603b56965ac026380ded42b0 (diff)
Add support for some string functions, the scanf family, and sprintf
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11673 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/DataStructure')
-rw-r--r--lib/Analysis/DataStructure/Local.cpp70
1 files changed, 66 insertions, 4 deletions
diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp
index 28bbef23f2..a3a0e2ebc6 100644
--- a/lib/Analysis/DataStructure/Local.cpp
+++ b/lib/Analysis/DataStructure/Local.cpp
@@ -484,7 +484,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
if (DSNode *N = RetNH.getNode())
N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
return;
- } else if (F->getName() == "atoi") {
+ } else if (F->getName() == "atoi" || F->getName() == "atof") {
// atoi reads its argument.
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
N->setReadMarker();
@@ -549,7 +549,8 @@ void GraphBuilder::visitCallSite(CallSite CS) {
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
H.getNode()->mergeTypeInfo(PTy->getElementType(), H.getOffset());
return;
- } else if (F->getName() == "printf" || F->getName() == "fprintf") {
+ } else if (F->getName() == "printf" || F->getName() == "fprintf" ||
+ F->getName() == "sprintf") {
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
if (F->getName() == "fprintf") {
@@ -562,6 +563,16 @@ void GraphBuilder::visitCallSite(CallSite CS) {
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
}
+ } else if (F->getName() == "sprintf") {
+ // sprintf writes the first string argument.
+ DSNodeHandle H = getValueDest(**AI++);
+ if (DSNode *N = H.getNode()) {
+ N->setModifiedMarker();
+ const Type *ArgTy = (*AI)->getType();
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ }
+
}
for (; AI != E; ++AI) {
@@ -570,9 +581,60 @@ void GraphBuilder::visitCallSite(CallSite CS) {
if (DSNode *N = getValueDest(**AI).getNode())
N->setReadMarker();
}
+ } else if (F->getName() == "scanf" || F->getName() == "fscanf" ||
+ F->getName() == "sscanf") {
+ CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
+
+ if (F->getName() == "fscanf") {
+ // fscanf reads and writes the FILE argument, and applies the type
+ // to it.
+ DSNodeHandle H = getValueDest(**AI);
+ if (DSNode *N = H.getNode()) {
+ N->setReadMarker();
+ const Type *ArgTy = (*AI)->getType();
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ }
+ } else if (F->getName() == "sscanf") {
+ // sscanf reads the first string argument.
+ DSNodeHandle H = getValueDest(**AI++);
+ if (DSNode *N = H.getNode()) {
+ N->setReadMarker();
+ const Type *ArgTy = (*AI)->getType();
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ }
+ }
+
+ for (; AI != E; ++AI) {
+ // scanf writes all pointer arguments.
+ if (isPointerType((*AI)->getType()))
+ if (DSNode *N = getValueDest(**AI).getNode())
+ N->setModifiedMarker();
+ }
+ } else if (F->getName() == "strtok") {
+ // strtok reads and writes the first argument, returning it. It reads
+ // its second arg. FIXME: strtok also modifies some hidden static
+ // data. Someday this might matter.
+ CallSite::arg_iterator AI = CS.arg_begin();
+ DSNodeHandle H = getValueDest(**AI++);
+ if (DSNode *N = H.getNode()) {
+ N->setReadMarker()->setModifiedMarker(); // Reads/Writes buffer
+ const Type *ArgTy = F->getFunctionType()->getParamType(0);
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ }
+ H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
+
+ H = getValueDest(**AI); // Reads delimiter
+ if (DSNode *N = H.getNode()) {
+ N->setReadMarker();
+ const Type *ArgTy = F->getFunctionType()->getParamType(1);
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ }
+ return;
- } else if (F->getName() == "exit") {
- // Nothing to do!
} else {
// Unknown function, warn if it returns a pointer type or takes a
// pointer argument.