diff --git a/lib/bcheck.c b/lib/bcheck.c
index b8dd1c53..e05209c6 100644
--- a/lib/bcheck.c
+++ b/lib/bcheck.c
@@ -41,7 +41,7 @@
 #define BOUND_STATISTIC         (1)
 
 #if BOUND_DEBUG
- #define dprintf(a...)         if (print_calls) fprintf(a)
+ #define dprintf(a...)         if (print_calls) { bounds_loc; fprintf(a); }
 #else
  #define dprintf(a...)
 #endif
@@ -446,6 +446,7 @@ static unsigned long long bound_splay_delete;
 #endif
 
 int tcc_backtrace(const char *fmt, ...);
+void tcc_location(const char *fmt);
 
 /* print a bound error message */
 #define bound_warning(...) \
@@ -462,6 +463,13 @@ int tcc_backtrace(const char *fmt, ...);
             exit(255);              \
     } while (0)
 
+#define bounds_loc \
+    do {                            \
+        WAIT_SEM (); \
+        tcc_location("^bcheck.c^"); \
+        POST_SEM (); \
+    } while (0)
+
 static void bound_alloc_error(const char *s)
 {
     fprintf(stderr,"FATAL: %s\n",s);
diff --git a/lib/bt-dll.c b/lib/bt-dll.c
index 7c62cefa..00c67da7 100644
--- a/lib/bt-dll.c
+++ b/lib/bt-dll.c
@@ -8,6 +8,7 @@
   REDIR(__bt_init) \
   REDIR(__bt_exit) \
   REDIR(tcc_backtrace) \
+  REDIR(tcc_location) \
   \
   REDIR(__bound_ptr_add) \
   REDIR(__bound_ptr_indir1) \
diff --git a/lib/bt-exe.c b/lib/bt-exe.c
index 3a2d02e4..7cd56e70 100644
--- a/lib/bt-exe.c
+++ b/lib/bt-exe.c
@@ -8,6 +8,7 @@
 #include "../tccrun.c"
 
 int (*__rt_error)(void*, void*, const char *, va_list);
+void (*__rt_location)(void*, void*, const char *);
 __attribute__((weak)) void __bound_checking_lock(void);
 __attribute__((weak)) void __bound_checking_unlock(void);
 
@@ -33,6 +34,7 @@ void __bt_init(rt_context *p, int num_callers)
         rc->num_callers = num_callers - 1;
         rc->top_func = main;
         __rt_error = _rt_error;
+        __rt_location = _rt_location;
         set_exception_handler();
     } else {
         p->next = rc->next, rc->next = p;
diff --git a/lib/bt-log.c b/lib/bt-log.c
index 8f7a4dbb..c6a11146 100644
--- a/lib/bt-log.c
+++ b/lib/bt-log.c
@@ -6,6 +6,7 @@
 #include <string.h>
 
 int (*__rt_error)(void*, void*, const char *, va_list);
+void (*__rt_location)(void*, void*, const char *);
 
 #ifdef _WIN32
 # define DLL_EXPORT __declspec(dllexport)
@@ -42,6 +43,15 @@ DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
     return ret;
 }
 
+DLL_EXPORT void tcc_location(const char *fmt)
+{
+    if (__rt_location) {
+        void *fp = __builtin_frame_address(1);
+        void *ip = __builtin_return_address(0);
+        __rt_location(fp, ip, fmt);
+    }
+}
+
 #if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
 #pragma GCC diagnostic pop
 #endif
diff --git a/tccgen.c b/tccgen.c
index 205c27f7..88436a83 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -6010,6 +6010,7 @@ special_math_val:
                 indir();
             qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
             test_lvalue();
+            gaddrof();
             /* expect pointer on structure */
             if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
                 expect("struct or union");
@@ -6020,15 +6021,16 @@ special_math_val:
                 expect("field name");
 	    s = find_field(&vtop->type, tok, &cumofs);
             /* add field offset to pointer */
-            incr_offset(cumofs);
+            vtop->type = char_pointer_type; /* change type to 'char *' */
+            vpushi(cumofs);
+            gen_op('+');
             /* change type to field type, and set to lvalue */
             vtop->type = s->type;
             vtop->type.t |= qualifiers;
             /* an array is never an lvalue */
-            if (vtop->type.t & VT_ARRAY) {
-                vtop->r &= ~VT_LVAL;
+            if (!(vtop->type.t & VT_ARRAY)) {
+                vtop->r |= VT_LVAL;
 #ifdef CONFIG_TCC_BCHECK
-            } else {
                 /* if bound checking, the referenced pointer must be checked */
                 if (tcc_state->do_bounds_check)
                     vtop->r |= VT_MUSTBOUND;
diff --git a/tccrun.c b/tccrun.c
index d373abca..40545ad0 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -53,6 +53,7 @@ typedef struct rt_context
 static rt_context g_rtctxt;
 static void set_exception_handler(void);
 static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap);
+static void _rt_location(void *fp, void *ip, const char *fmt);
 static void rt_exit(int code);
 #endif /* CONFIG_TCC_BACKTRACE */
 
@@ -274,6 +275,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
         rc->do_jmp = 1;
         if ((p = tcc_get_symbol(s1, "__rt_error")))
             *(void**)p = _rt_error;
+        if ((p = tcc_get_symbol(s1, "__rt_location")))
+            *(void**)p = _rt_location;
 #ifdef CONFIG_TCC_BCHECK
         if (s1->do_bounds_check) {
             rc->bounds_start = (void*)bounds_section->sh_addr;
@@ -1089,6 +1092,41 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
     return 0;
 }
 
+static void _rt_location(void *fp, void *ip, const char *fmt)
+{
+    rt_context *rc = &g_rtctxt;
+    addr_t pc = 0;
+    char skip[100];
+    int i, ret;
+    const char *a, *b;
+
+    rc->fp = (addr_t)fp;
+    rc->ip = (addr_t)ip;
+
+    skip[0] = 0;
+    /* If fmt is like "^file.c^..." then skip calls from 'file.c' */
+    if (fmt[0] == '^' && (b = strchr(a = fmt + 1, fmt[0])))
+        memcpy(skip, a, b - a), skip[b - a] = 0;
+
+    for (i = 0; ; i++) {
+        ret = rt_get_caller_pc(&pc, rc, i);
+        a = "";
+        if (ret != -1) {
+            if (rc->dwarf)
+                pc = rt_printline_dwarf(rc, pc, "at", skip);
+            else
+                pc = rt_printline(rc, pc, "at", skip);
+            if (pc == (addr_t)-1)
+                continue;
+            a = ": ";
+        }
+        rt_printf(a);
+        break;
+    }
+
+    rc->ip = rc->fp = 0;
+}
+
 /* emit a run time error at position 'pc' */
 static int rt_error(const char *fmt, ...)
 {
diff --git a/tests/tests2/132_bound_test.c b/tests/tests2/132_bound_test.c
new file mode 100644
index 00000000..4898e8d7
--- /dev/null
+++ b/tests/tests2/132_bound_test.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <float.h>
+
+union ieee_double_extract
+{
+    struct {
+        unsigned int manl:32;
+        unsigned int manh:20;
+        unsigned int exp:11;
+        unsigned int sig:1;
+    } s;
+    double d;
+};
+
+double scale(double d)
+{
+    union ieee_double_extract x;
+
+    x.d = d;
+    x.d *= 1000;
+    return x.d;
+}
+
+int
+main(void)
+{
+    printf("%g\n", scale(42));
+    return 0;
+}
diff --git a/tests/tests2/132_bound_test.expect b/tests/tests2/132_bound_test.expect
new file mode 100644
index 00000000..6096bd1b
--- /dev/null
+++ b/tests/tests2/132_bound_test.expect
@@ -0,0 +1 @@
+42000