]> granicus.if.org Git - clang/commitdiff
[CodeGen] Don't UBSan-ize the argument to __builtin_frame_address
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 25 Jul 2015 05:57:24 +0000 (05:57 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 25 Jul 2015 05:57:24 +0000 (05:57 +0000)
__builtin_frame_address requires its argument to be a constant
expression which already implies that it cannot have undefined behavior.
However, we used EmitScalarExpr to emit the argument causing UBSan to
try to check for overflow.

Instead, use the constant expression emission system.

This fixes PR24256.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@243206 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBuiltin.cpp
test/CodeGen/integer-overflow.c

index 463b3eee3d35b3330210cf71d022f8b429e18259..9b8694f9c5f213849f7c89a178a8f3572a39f24b 100644 (file)
@@ -866,14 +866,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
                                       llvm::ConstantInt::get(Int32Ty, Offset)));
   }
   case Builtin::BI__builtin_return_address: {
-    Value *Depth = EmitScalarExpr(E->getArg(0));
-    Depth = Builder.CreateIntCast(Depth, Int32Ty, false);
+    Value *Depth =
+        CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this);
     Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
   case Builtin::BI__builtin_frame_address: {
-    Value *Depth = EmitScalarExpr(E->getArg(0));
-    Depth = Builder.CreateIntCast(Depth, Int32Ty, false);
+    Value *Depth =
+        CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this);
     Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
index de3b53f4b5b36752f2869abf7d7077be0a02e6ba..6a7c3e51ee1bb699c6fc6803a8d6958ff84f59fd 100644 (file)
@@ -72,4 +72,11 @@ void test1() {
   // TRAPV: add i8 {{.*}}, 1
   // CATCH_UB: add i8 {{.*}}, 1
   ++PR9350;
+
+  // PR24256: don't instrument __builtin_frame_address.
+  __builtin_frame_address(0 + 0);
+  // DEFAULT:  call i8* @llvm.frameaddress(i32 0)
+  // WRAPV:    call i8* @llvm.frameaddress(i32 0)
+  // TRAPV:    call i8* @llvm.frameaddress(i32 0)
+  // CATCH_UB: call i8* @llvm.frameaddress(i32 0)
 }