aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-11-09 04:57:04 +0000
committerChris Lattner <sabre@nondot.org>2009-11-09 04:57:04 +0000
commit74965f2279af05246a0f9fe4ab50643fea9aa9b0 (patch)
tree4bd9afdaef8b880b8d3be5e0065d95526ccd2402 /lib/Transforms
parent0dd3b7645b47118f7bea9d676a4176f96f76c457 (diff)
downloadexternal_llvm-74965f2279af05246a0f9fe4ab50643fea9aa9b0.zip
external_llvm-74965f2279af05246a0f9fe4ab50643fea9aa9b0.tar.gz
external_llvm-74965f2279af05246a0f9fe4ab50643fea9aa9b0.tar.bz2
fix PR5104: when printing a single character, return the result of
putchar in case there is an error. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp22
1 files changed, 13 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index ecca3c7..296f0c9 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -100,7 +100,7 @@ public:
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
- void EmitPutChar(Value *Char, IRBuilder<> &B);
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B);
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
@@ -252,7 +252,7 @@ Value *LibCallOptimization::EmitUnaryFloatFnCall(Value *Op, const char *Name,
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
-void LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
+Value *LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
Module *M = Caller->getParent();
Value *PutChar = M->getOrInsertFunction("putchar", Type::getInt32Ty(*Context),
Type::getInt32Ty(*Context), NULL);
@@ -264,6 +264,7 @@ void LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
CI->setCallingConv(F->getCallingConv());
+ return CI;
}
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
@@ -1325,11 +1326,13 @@ struct PrintFOpt : public LibCallOptimization {
return CI->use_empty() ? (Value*)CI :
ConstantInt::get(CI->getType(), 0);
- // printf("x") -> putchar('x'), even for '%'.
+ // printf("x") -> putchar('x'), even for '%'. Return the result of putchar
+ // in case there is an error writing to stdout.
if (FormatStr.size() == 1) {
- EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context), FormatStr[0]), B);
- return CI->use_empty() ? (Value*)CI :
- ConstantInt::get(CI->getType(), 1);
+ Value *Res = EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context),
+ FormatStr[0]), B);
+ if (CI->use_empty()) return CI;
+ return B.CreateIntCast(Res, CI->getType(), true);
}
// printf("foo\n") --> puts("foo")
@@ -1350,9 +1353,10 @@ struct PrintFOpt : public LibCallOptimization {
// printf("%c", chr) --> putchar(*(i8*)dst)
if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
isa<IntegerType>(CI->getOperand(2)->getType())) {
- EmitPutChar(CI->getOperand(2), B);
- return CI->use_empty() ? (Value*)CI :
- ConstantInt::get(CI->getType(), 1);
+ Value *Res = EmitPutChar(CI->getOperand(2), B);
+
+ if (CI->use_empty()) return CI;
+ return B.CreateIntCast(Res, CI->getType(), true);
}
// printf("%s\n", str) --> puts(str)