Emit an error message if the value passed to __builtin_returnaddress isn't a constant
authorBill Wendling <isanbard@gmail.com>
Sun, 5 Jan 2014 01:47:20 +0000 (01:47 +0000)
committerBill Wendling <isanbard@gmail.com>
Sun, 5 Jan 2014 01:47:20 +0000 (01:47 +0000)
__builtin_returnaddress requires that the value passed into is be a constant.
However, at -O0 even a constant expression may not be converted to a constant.
Emit an error message intead of crashing.

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

lib/Target/AArch64/AArch64ISelLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/Hexagon/HexagonISelLowering.cpp
lib/Target/MSP430/MSP430ISelLowering.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/Sparc/SparcISelLowering.cpp
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/Generic/builtin-returnaddress-error.ll [new file with mode: 0644]

index 882b5280fa14a0e374abcf9dd0e1870cab5d4634..b4bd0194ee4ae1d5c877e7f945bd31533488ee35 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/IR/CallingConv.h"
+#include "llvm/IR/LLVMContext.h"
 
 using namespace llvm;
 
@@ -2131,6 +2132,12 @@ SDValue AArch64TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) co
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   EVT VT = Op.getValueType();
   SDLoc dl(Op);
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
index 017c86667ed246de8c21e37a67455aa088928b08..ef165dc06e26cb37b03dd4f67a9d1dc7dcadecb7 100644 (file)
@@ -41,6 +41,7 @@
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Type.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/Support/CommandLine.h"
@@ -3752,6 +3753,12 @@ SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   EVT VT = Op.getValueType();
   SDLoc dl(Op);
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
index 137417966976ba30ff3dcae15ae5fc4e560a16df..e1e954afc5127fbe0fe4f3ef1fa99b0f07439be8 100644 (file)
@@ -32,6 +32,7 @@
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -981,6 +982,12 @@ HexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   EVT VT = Op.getValueType();
   SDLoc dl(Op);
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
index 745cdf5bc792a9265eaf5b861fd18ab13357b6fc..a1a7c5e08ef874231deead1c9920f35bac06c515 100644 (file)
@@ -32,6 +32,7 @@
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1047,6 +1048,12 @@ SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
   MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
   SDLoc dl(Op);
 
index 9c74ae4ce2b162b43f487451343d8e15a2e9bb80..220b1c4a3507766395ec3ca6c4ac934904abd5d6 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -1844,6 +1845,12 @@ lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
 
 SDValue MipsTargetLowering::lowerRETURNADDR(SDValue Op,
                                             SelectionDAG &DAG) const {
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   // check the depth
   assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) &&
          "Return address can be determined only for current frame.");
index a00e37ab988c839b12641fad736809a8384c6025..630385cc7c0c564ee46fb1c668f504852233031d 100644 (file)
@@ -30,6 +30,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
@@ -7795,6 +7796,12 @@ SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op,
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   SDLoc dl(Op);
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
 
index c59d523b6b174743ff6a79986bd5f6774ace6147..5442e5704c1fb0e769638e82de70365a7deebfe6 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace llvm;
@@ -2470,6 +2471,12 @@ static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG,
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   EVT VT = Op.getValueType();
   SDLoc dl(Op);
   uint64_t depth = Op.getConstantOperandVal(0);
index 5e19f2802fecd74bcb3f17fa3efb56f9db44c6b4..f4a2f692185189545ccad7cd372a2b606d766553 100644 (file)
@@ -12180,6 +12180,12 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
   MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
 
+  if (!isa<ConstantSDNode>(Op.getOperand(0))) {
+    DAG.getContext()->emitError("argument to '__builtin_return_address' must "
+                                "be a constant integer");
+    return SDValue();
+  }
+
   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
   SDLoc dl(Op);
   EVT PtrVT = getPointerTy();
diff --git a/test/CodeGen/Generic/builtin-returnaddress-error.ll b/test/CodeGen/Generic/builtin-returnaddress-error.ll
new file mode 100644 (file)
index 0000000..d3bd157
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: not llc < %s -O0 2> %t1
+; RUN: FileCheck %s < %t1
+
+; CHECK: argument to '__builtin_return_address' must be a constant integer
+
+define i32* @foo() {
+entry:
+  %t1 = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 0, i32 0)
+  %t2 = extractvalue { i32, i1 } %t1, 0
+  %t3 = extractvalue { i32, i1 } %t1, 1
+  br i1 %t3, label %cont, label %trap
+
+trap:
+  call void @llvm.trap()
+  unreachable
+
+cont:
+  %t5 = call i8* @llvm.returnaddress(i32 %t2)
+  %t6 = bitcast i8* %t5 to i32*
+  ret i32* %t6
+}
+
+declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
+
+declare void @llvm.trap()
+
+declare i8* @llvm.returnaddress(i32)