From 238e760a294ca74e46d8545f0fb80ea2af522f2b Mon Sep 17 00:00:00 2001
From: Edmund Grimley Evans <Edmund.Grimley.Evans@gmail.com>
Date: Fri, 6 Mar 2015 21:01:14 +0000
Subject: [PATCH] Add __builtin_return_address.

Implementation is mostly shared with __builtin_frame_address.
It seems to work on arm64, i386 and x86_64. It may need to be
adapted for other targets.
---
 tccgen.c | 14 +++++++++++++-
 tcctok.h |  1 +
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/tccgen.c b/tccgen.c
index e86ff4ab..3b1336ca 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3874,13 +3874,18 @@ ST_FUNC void unary(void)
         }
         break;
     case TOK_builtin_frame_address:
+    case TOK_builtin_return_address:
         {
+            int tok1 = tok;
             int level;
             CType type;
             next();
             skip('(');
             if (tok != TOK_CINT || tokc.i < 0) {
-                tcc_error("__builtin_frame_address only takes positive integers");
+                tcc_error("%s only takes positive integers",
+                          tok1 == TOK_builtin_return_address ?
+                          "__builtin_return_address" :
+                          "__builtin_frame_address");
             }
             level = tokc.i;
             next();
@@ -3892,6 +3897,13 @@ ST_FUNC void unary(void)
                 mk_pointer(&vtop->type);
                 indir();                    /* -> parent frame */
             }
+            if (tok1 == TOK_builtin_return_address) {
+                // assume return address is just above frame pointer on stack
+                vpushi(PTR_SIZE);
+                gen_op('+');
+                mk_pointer(&vtop->type);
+                indir();
+            }
         }
         break;
 #ifdef TCC_TARGET_X86_64
diff --git a/tcctok.h b/tcctok.h
index 9fba4556..d78eb93d 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -130,6 +130,7 @@
      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
      DEF(TOK_builtin_frame_address, "__builtin_frame_address")
+     DEF(TOK_builtin_return_address, "__builtin_return_address")
 #ifdef TCC_TARGET_X86_64
 #ifdef TCC_TARGET_PE
      DEF(TOK_builtin_va_start, "__builtin_va_start")