Hi!

Another problem from the compiler side when working on the asan testsuite
is that at higher -O* levels the __asan_report_* noreturn calls are
cross-jumped, but the library relies on their locus to print accurrate
locations when symbolized.  Without it, asan might report an error
completely elsewhere in a function.

This patch disables cross-jumping of such builtins.
Alternatively, I could introduce some attribute (no_cross_jump?),
ECF_NO_CROSS_JUMP, add those attributes to those builtins (and let users
add those too to functions they wish), and look at ECF_NO_CROSS_JUMP instead
during cross-jumping.

2012-12-05  Jakub Jelinek  <ja...@redhat.com>

        * sanitizer.def: Add comment about importance of ordering of
        BUILT_IN_ASAN_REPORT* builtins.
        * cfgcleanup.c (old_insns_match_p): Don't cross-jump __asan_report_*
        builtins.

--- gcc/sanitizer.def.jj        2012-12-04 14:19:36.000000000 +0100
+++ gcc/sanitizer.def   2012-12-05 09:38:01.205958515 +0100
@@ -29,6 +29,8 @@ along with GCC; see the file COPYING3.
 /* Address Sanitizer */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init",
                      BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
+/* Do not reorder the BUILT_IN_ASAN_REPORT* builtins, e.g. cfgcleanup.c
+   relies on this order.  */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
                      BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD2, "__asan_report_load2",
--- gcc/cfgcleanup.c.jj 2012-11-20 09:37:47.000000000 +0100
+++ gcc/cfgcleanup.c    2012-12-05 09:37:23.389181984 +0100
@@ -1138,6 +1138,28 @@ old_insns_match_p (int mode ATTRIBUTE_UN
                        CALL_INSN_FUNCTION_USAGE (i2))
          || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2))
        return dir_none;
+
+      /* For address sanitizer, never crossjump __asan_report_* builtins,
+        otherwise errors might be reported on incorrect lines.  */
+      if (flag_asan)
+       {
+         rtx call = get_call_rtx_from (i1);
+         if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
+           {
+             rtx symbol = XEXP (XEXP (call, 0), 0);
+             if (SYMBOL_REF_DECL (symbol)
+                 && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
+               {
+                 if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
+                      == BUILT_IN_NORMAL)
+                     && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
+                        >= BUILT_IN_ASAN_REPORT_LOAD1
+                     && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
+                        <= BUILT_IN_ASAN_REPORT_STORE16)
+                   return dir_none;
+               }
+           }
+       }
     }
 
 #ifdef STACK_REGS

        Jakub

Reply via email to