diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp index 2a04d291283..16e3cbaed41 100644 --- a/lib/Analysis/DataStructure/Local.cpp +++ b/lib/Analysis/DataStructure/Local.cpp @@ -493,6 +493,33 @@ void GraphBuilder::visitCallSite(CallSite CS) { if (DSNode *N = H.getNode()) N->setModifiedMarker(); return; + } else if (F->getName() == "fopen" && CS.arg_end()-CS.arg_begin() == 2){ + // fopen reads the mode argument strings. + CallSite::arg_iterator AI = CS.arg_begin(); + DSNodeHandle Path = getValueDest(**AI); + DSNodeHandle Mode = getValueDest(**++AI); + if (DSNode *N = Path.getNode()) N->setReadMarker(); + if (DSNode *N = Mode.getNode()) N->setReadMarker(); + + // fopen allocates in an unknown way and writes to the file + // descriptor. Also, merge the allocated type into the node. + DSNodeHandle Result = getValueDest(*CS.getInstruction()); + Result.getNode()->setModifiedMarker()->setUnknownNodeMarker(); + const Type *RetTy = F->getFunctionType()->getReturnType(); + if (const PointerType *PTy = dyn_cast(RetTy)) + Result.getNode()->mergeTypeInfo(PTy->getElementType(), + Result.getOffset()); + return; + } else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){ + // fclose reads and deallocates the memory in an unknown way for the + // file descriptor. It merges the FILE type into the descriptor. + DSNodeHandle H = getValueDest(**CS.arg_begin()); + H.getNode()->setReadMarker()->setUnknownNodeMarker(); + + const Type *ArgTy = *F->getFunctionType()->param_begin(); + if (const PointerType *PTy = dyn_cast(ArgTy)) + H.getNode()->mergeTypeInfo(PTy->getElementType(), H.getOffset()); + return; } }