mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-31 09:11:13 +00:00
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
This commit is contained in:
parent
3da125839d
commit
8ecc27e667
@ -484,7 +484,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (DSNode *N = RetNH.getNode())
|
if (DSNode *N = RetNH.getNode())
|
||||||
N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
|
N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
|
||||||
return;
|
return;
|
||||||
} else if (F->getName() == "atoi") {
|
} else if (F->getName() == "atoi" || F->getName() == "atof") {
|
||||||
// atoi reads its argument.
|
// atoi reads its argument.
|
||||||
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
|
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
@ -549,7 +549,8 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
||||||
H.getNode()->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
H.getNode()->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
||||||
return;
|
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();
|
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
||||||
|
|
||||||
if (F->getName() == "fprintf") {
|
if (F->getName() == "fprintf") {
|
||||||
@ -562,6 +563,16 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
||||||
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
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) {
|
for (; AI != E; ++AI) {
|
||||||
@ -570,9 +581,60 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setReadMarker();
|
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 {
|
} else {
|
||||||
// Unknown function, warn if it returns a pointer type or takes a
|
// Unknown function, warn if it returns a pointer type or takes a
|
||||||
// pointer argument.
|
// pointer argument.
|
||||||
|
Loading…
Reference in New Issue
Block a user