summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-02-13 21:21:48 +0000
committerChris Lattner <sabre@nondot.org>2004-02-13 21:21:48 +0000
commit339d8df4c04c5d0be8dc70722153d94cfef7171a (patch)
treeb83ee03ad433fd8818f7c4ffe11ebd0b7059eec6
parentbe766c72464116a445a02b542a450c4274bab5d0 (diff)
downloadllvm-339d8df4c04c5d0be8dc70722153d94cfef7171a.tar.gz
llvm-339d8df4c04c5d0be8dc70722153d94cfef7171a.tar.bz2
llvm-339d8df4c04c5d0be8dc70722153d94cfef7171a.tar.xz
Add support for a bunch more functions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11395 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/DataStructure/Local.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp
index 16e3cbaed4..31aa76b3bb 100644
--- a/lib/Analysis/DataStructure/Local.cpp
+++ b/lib/Analysis/DataStructure/Local.cpp
@@ -520,6 +520,62 @@ 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() == "fflush" && CS.arg_end()-CS.arg_begin() ==1){
+ // fclose reads and writes the memory for the file descriptor. It
+ // merges the FILE type into the descriptor.
+ DSNodeHandle H = getValueDest(**CS.arg_begin());
+ H.getNode()->setReadMarker()->setModifiedMarker();
+
+ const Type *ArgTy = *F->getFunctionType()->param_begin();
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ H.getNode()->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ return;
+ } else if (F->getName() == "fgets" && CS.arg_end()-CS.arg_begin() == 3){
+ // fclose reads and writes the memory for the file descriptor. It
+ // merges the FILE type into the descriptor, and writes to the
+ // argument. It returns the argument as well.
+ CallSite::arg_iterator AI = CS.arg_begin();
+ DSNodeHandle H = getValueDest(**AI);
+ if (DSNode *N = H.getNode())
+ N->setModifiedMarker(); // Writes buffer
+ H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
+ ++AI; ++AI;
+
+ // Reads and writes file descriptor, merge in FILE type.
+ H = getValueDest(**CS.arg_begin());
+ if (DSNode *N = H.getNode())
+ N->setReadMarker()->setModifiedMarker();
+ const Type *ArgTy = *(F->getFunctionType()->param_begin()+2);
+ if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
+ H.getNode()->mergeTypeInfo(PTy->getElementType(), H.getOffset());
+ return;
+ } else if (F->getName() == "printf" || F->getName() == "fprintf") {
+ CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
+
+ if (F->getName() == "fprintf") {
+ // fprintf reads and writes the FILE argument, and applies the type
+ // to it.
+ 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) {
+ // printf reads all pointer arguments.
+ if (isPointerType((*AI)->getType()))
+ if (DSNode *N = getValueDest(**AI).getNode())
+ N->setReadMarker();
+ }
+
+ } else if (F->getName() == "exit") {
+ // Nothing to do!
+ } else {
+ std::cerr << "WARNING: Call to unknown external function '"
+ << F->getName() << "' will cause pessimistic results!\n";
}
}