diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-03-22 00:47:07 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-03-22 00:47:07 +0000 |
commit | bf8487a3c290203ae54fd81d35a94be0ff211235 (patch) | |
tree | 60abe5319308c1d46397e98259e20a3566106821 | |
parent | daf2e1c636799535a7eb058ffab93cdf52f466cb (diff) |
ubsan: Pass floating-point arguments to the runtime by value if they fit the
value argument. If not, be sure we don't accidentally use a dynamic alloca.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177690 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 11 | ||||
-rw-r--r-- | test/CodeGen/catch-undef-behavior.c | 27 |
2 files changed, 36 insertions, 2 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index ad69ebe05f..9bfaacbbd6 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2078,6 +2078,15 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) { llvm::Type *TargetTy = IntPtrTy; + // Floating-point types which fit into intptr_t are bitcast to integers + // and then passed directly (after zero-extension, if necessary). + if (V->getType()->isFloatingPointTy()) { + unsigned Bits = V->getType()->getPrimitiveSizeInBits(); + if (Bits <= TargetTy->getIntegerBitWidth()) + V = Builder.CreateBitCast(V, llvm::Type::getIntNTy(getLLVMContext(), + Bits)); + } + // Integers which fit in intptr_t are zero-extended and passed directly. if (V->getType()->isIntegerTy() && V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth()) @@ -2085,7 +2094,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) { // Pointers are passed directly, everything else is passed by address. if (!V->getType()->isPointerTy()) { - llvm::Value *Ptr = Builder.CreateAlloca(V->getType()); + llvm::Value *Ptr = CreateTempAlloca(V->getType()); Builder.CreateStore(V, Ptr); V = Ptr; } diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c index bd4973c069..8e3388ea63 100644 --- a/test/CodeGen/catch-undef-behavior.c +++ b/test/CodeGen/catch-undef-behavior.c @@ -288,7 +288,10 @@ int float_int_overflow(float f) { // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000 // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000 // CHECK: and i1 %[[GE]], %[[LE]] - // CHECK: call void @__ubsan_handle_float_cast_overflow( + + // CHECK: %[[CAST:.*]] = bitcast float %[[F]] to i32 + // CHECK: %[[ARG:.*]] = zext i32 %[[CAST]] to i64 + // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] // CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000 // CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000 @@ -300,6 +303,28 @@ int float_int_overflow(float f) { return f; } +// CHECK: @long_double_int_overflow +// CHECK-TRAP: @long_double_int_overflow +int long_double_int_overflow(long double ld) { + // CHECK: alloca x86_fp80 + // CHECK: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E8000000100000000 + // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000 + // CHECK: and i1 %[[GE]], %[[LE]] + + // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]] + // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64 + // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] + + // CHECK-TRAP: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E800000010000000 + // CHECK-TRAP: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E800000000000000 + // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]] + // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] + + // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] + // CHECK-TRAP-NEXT: unreachable + return ld; +} + // CHECK: @float_uint_overflow // CHECK-TRAP: @float_uint_overflow unsigned float_uint_overflow(float f) { |