diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-02-20 20:27:11 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-02-20 20:27:11 +0000 | 
| commit | 8ecc27e66750077724539a02b5c20d8b942a8e50 (patch) | |
| tree | 4a75c0a1b852a8b759a2d37c01df0f9d63eacd5d /lib/Analysis/DataStructure/Local.cpp | |
| parent | 3da125839d61e0bb603b56965ac026380ded42b0 (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/Local.cpp')
| -rw-r--r-- | lib/Analysis/DataStructure/Local.cpp | 70 | 
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.  | 
