diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2568,6 +2568,14 @@ case Builtin::BI__builtin_return_address: { Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), getContext().UnsignedIntTy); + llvm::ConstantInt* DepthConstVal = dyn_cast(Depth); + if (!DepthConstVal) + CGM.ErrorUnsupported(E, + "argument to '__builtin_return_address' must be a constant integer"); + if (DepthConstVal->getSExtValue() < 0) + CGM.ErrorUnsupported(E, + "argument to '__builtin_return_address' must be at least 0"); + Function *F = CGM.getIntrinsic(Intrinsic::returnaddress); return RValue::get(Builder.CreateCall(F, Depth)); } @@ -2578,6 +2586,14 @@ case Builtin::BI__builtin_frame_address: { Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), getContext().UnsignedIntTy); + llvm::ConstantInt* DepthConstVal = dyn_cast(Depth); + if (!DepthConstVal) + CGM.ErrorUnsupported(E, + "argument to '__builtin_frame_address' must be a constant integer"); + if (DepthConstVal->getSExtValue() < 0) + CGM.ErrorUnsupported(E, + "argument to '__builtin_frame_address' must be at least 0"); + Function *F = CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy); return RValue::get(Builder.CreateCall(F, Depth)); } diff --git a/clang/test/Sema/builtin-stackaddress.c b/clang/test/Sema/builtin-stackaddress.c --- a/clang/test/Sema/builtin-stackaddress.c +++ b/clang/test/Sema/builtin-stackaddress.c @@ -1,16 +1,30 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 %s + void* a(unsigned x) { return __builtin_return_address(0); } void b(unsigned x) { -return __builtin_return_address(x); // expected-error{{argument to '__builtin_return_address' must be a constant integer}} +// TODO: lit doesn't catch this +// expected-error@+1 {{argument to '__builtin_return_address' must be a constant integer}} +return __builtin_return_address(x); } void* c(unsigned x) { +// expected-error@+1 {{argument to '__builtin_return_address' must be at least 0}} +return __builtin_return_address(-1); +} + +void* d(unsigned x) { return __builtin_frame_address(0); } -void d(unsigned x) { -return __builtin_frame_address(x); // expected-error{{argument to '__builtin_frame_address' must be a constant integer}} +void e(unsigned x) { +// expected-error@+1 {{argument to '__builtin_frame_address' must be a constant integer}} +return __builtin_frame_address(x); +} + +void* f(unsigned x) { +// expected-error@+1 {{argument to '__builtin_frame_address' must be at least 0}} +return __builtin_frame_address(-1); }