]> granicus.if.org Git - clang/commitdiff
Add __builtin_frame_address and __builtin_return_address gcc builtins to
authorEli Friedman <eli.friedman@gmail.com>
Tue, 20 May 2008 08:23:37 +0000 (08:23 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 20 May 2008 08:23:37 +0000 (08:23 +0000)
Sema. No codegen yet.

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

include/clang/AST/Builtins.def
include/clang/Basic/DiagnosticKinds.def
lib/Sema/Sema.h
lib/Sema/SemaChecking.cpp
test/Sema/builtin-stackaddress.c [new file with mode: 0644]

index 4d3812fc941261e5820cc157c2c197e3ea7d5dcf..0016afdcb88e6c3a76e6d53fdd09ac80d17ebe24 100644 (file)
@@ -94,6 +94,8 @@ BUILTIN(__builtin_va_start, "va&.", "n")
 BUILTIN(__builtin_va_end, "va&", "n")
 BUILTIN(__builtin_va_copy, "va&a", "n")
 BUILTIN(__builtin_memcpy, "v*v*vC*z", "n")
+BUILTIN(__builtin_return_address, "v*Ui", "n")
+BUILTIN(__builtin_frame_address, "v*Ui", "n")
 // GCC Object size checking builtins
 BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "n")
 BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "n")
index b5fb1ddf6bf626474fd444193083c8812f48548a..3eb08e4b5577ca3812d255bbcf0b0f1832106b3b 100644 (file)
@@ -1069,4 +1069,7 @@ DIAG(err_shufflevector_nonconstant_argument, ERROR,
 DIAG(err_shufflevector_argument_too_large, ERROR,
      "indexes for __builtin_shufflevector must be less than the total number of vector elements")
 
+DIAG(err_stack_const_level, ERROR,
+     "the level argument for a stack address builtin must be constant")
+
 #undef DIAG
index b1b99966ddd09a848fd4d3d52252a3b0b82c37fa..b9b922a376ed5a98bbb511c54d2411394b565dea 100644 (file)
@@ -891,6 +891,7 @@ private:
   bool CheckBuiltinCFStringArgument(Expr* Arg);
   bool SemaBuiltinVAStart(CallExpr *TheCall);
   bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
+  bool SemaBuiltinStackAddress(CallExpr *TheCall);
   Action::ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
   void CheckPrintfArguments(CallExpr *TheCall,
                             bool HasVAListArg, unsigned format_idx);
index ce0036e399cd99229537f6c50b3bbf39e03cc29a..63c1635ef2b0a1e1715f6f2364187d44e116cb50 100644 (file)
@@ -58,6 +58,11 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCallRaw) {
     if (SemaBuiltinUnorderedCompare(TheCall.get()))
       return true;
     return TheCall.take();
+  case Builtin::BI__builtin_return_address:
+  case Builtin::BI__builtin_frame_address:
+    if (SemaBuiltinStackAddress(TheCall.get()))
+      return true;
+    return TheCall.take();
   case Builtin::BI__builtin_shufflevector:
     return SemaBuiltinShuffleVector(TheCall.get());
   }
@@ -177,7 +182,7 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) {
     Diag(TheCall->getArg(1)->getLocStart(), 
          diag::warn_second_parameter_of_va_start_not_last_named_argument);
   return false;
-}  
+}
 
 /// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
 /// friends.  This is declared to take (...), so we have to check everything.
@@ -209,6 +214,16 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
   return false;
 }
 
+bool Sema::SemaBuiltinStackAddress(CallExpr *TheCall) {
+  // The signature for these builtins is exact; the only thing we need
+  // to check is that the argument is a constant.
+  SourceLocation Loc;
+  if (!TheCall->getArg(0)->isIntegerConstantExpr(Context, &Loc)) {
+    return Diag(Loc, diag::err_stack_const_level, TheCall->getSourceRange());
+  }
+  return false;
+}
+
 /// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
 // This is declared to take (...), so we have to check everything.
 Action::ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
diff --git a/test/Sema/builtin-stackaddress.c b/test/Sema/builtin-stackaddress.c
new file mode 100644 (file)
index 0000000..a828168
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: clang -fsyntax-only -verify %s
+void* a(unsigned x) {
+return __builtin_return_address(0);
+}
+
+void b(unsigned x) {
+return __builtin_return_address(x); // expected-error{{the level argument for a stack address builtin must be constant}}
+}
+
+void* a(unsigned x) {
+return __builtin_frame_address(0);
+}
+
+void b(unsigned x) {
+return __builtin_frame_address(x); // expected-error{{the level argument for a stack address builtin must be constant}}
+}