On Thu, Sep 01, 2016 at 09:58:44AM +0200, Richard Biener wrote:
> Ah, so it expects sth _before_ before-dynamic-init?  At least it seems
> that globals are not only registered inbetween before/after-dynamic-init.

Here is updated patch, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk?

> Maybe simply always init dynamic_init_globals?

I've posted a patch to llvm-commits.

2016-09-02  Jakub Jelinek  <ja...@redhat.com>

        PR sanitizer/77396
        * sanopt.c: Include gimple-ssa.h, tree-phinodes.h and ssa-iterators.h.
        (sanopt_optimize_walker): Optimize away
        __asan_before_dynamic_init (...) followed by
        __asan_after_dynamic_init () without intervening memory loads/stores.
        * ipa-pure-const.c (special_builtin_state): Handle
        BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT and
        BUILT_IN_ASAN_AFTER_DYNAMIC_INIT.

        * decl2.c (do_static_initialization_or_destruction): Only
        call asan_dynamic_init_call if INITP is true.

        * g++.dg/asan/pr77396.C: New test.

--- gcc/sanopt.c.jj     2016-08-31 20:40:26.224215125 +0200
+++ gcc/sanopt.c        2016-09-02 13:30:09.954070468 +0200
@@ -33,6 +33,9 @@ along with GCC; see the file COPYING3.
 #include "ubsan.h"
 #include "params.h"
 #include "tree-hash-traits.h"
+#include "gimple-ssa.h"
+#include "tree-phinodes.h"
+#include "ssa-iterators.h"
 
 
 /* This is used to carry information about basic blocks.  It is
@@ -538,6 +541,28 @@ sanopt_optimize_walker (basic_block bb,
       if (asan_check_optimize && !nonfreeing_call_p (stmt))
        info->freeing_call_events++;
 
+      /* If __asan_before_dynamic_init ("module"); is followed by
+        __asan_after_dynamic_init (); without intervening memory loads/stores,
+        there is nothing to guard, so optimize both away.  */
+      if (asan_check_optimize
+         && gimple_call_builtin_p (stmt, BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT))
+       {
+         use_operand_p use;
+         gimple *use_stmt;
+         if (single_imm_use (gimple_vdef (stmt), &use, &use_stmt))
+           {
+             if (is_gimple_call (use_stmt)
+                 && gimple_call_builtin_p (use_stmt,
+                                           BUILT_IN_ASAN_AFTER_DYNAMIC_INIT))
+               {
+                 unlink_stmt_vdef (use_stmt);
+                 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
+                 gsi_remove (&gsi2, true);
+                 remove = true;
+               }
+           }
+       }
+
       if (gimple_call_internal_p (stmt))
        switch (gimple_call_internal_fn (stmt))
          {
--- gcc/ipa-pure-const.c.jj     2016-08-31 20:40:26.631209934 +0200
+++ gcc/ipa-pure-const.c        2016-09-02 13:24:55.173990290 +0200
@@ -508,6 +508,8 @@ special_builtin_state (enum pure_const_s
        case BUILT_IN_FRAME_ADDRESS:
        case BUILT_IN_APPLY:
        case BUILT_IN_APPLY_ARGS:
+       case BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT:
+       case BUILT_IN_ASAN_AFTER_DYNAMIC_INIT:
          *looping = false;
          *state = IPA_CONST;
          return true;
--- gcc/cp/decl2.c.jj   2016-08-31 20:40:26.577210623 +0200
+++ gcc/cp/decl2.c      2016-09-02 13:24:55.175990265 +0200
@@ -3861,7 +3861,7 @@ do_static_initialization_or_destruction
      in other compilation units, or at least those that haven't been
      initialized yet.  Variables that need dynamic construction in
      the current compilation unit are kept accessible.  */
-  if (flag_sanitize & SANITIZE_ADDRESS)
+  if (initp && (flag_sanitize & SANITIZE_ADDRESS))
     finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/false));
 
   node = vars;
@@ -3914,7 +3914,7 @@ do_static_initialization_or_destruction
 
   /* Revert what __asan_before_dynamic_init did by calling
      __asan_after_dynamic_init.  */
-  if (flag_sanitize & SANITIZE_ADDRESS)
+  if (initp && (flag_sanitize & SANITIZE_ADDRESS))
     finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/true));
 
   /* Finish up the init/destruct if-stmt body.  */
--- gcc/testsuite/g++.dg/asan/pr77396.C.jj      2016-09-02 13:24:55.175990265 
+0200
+++ gcc/testsuite/g++.dg/asan/pr77396.C 2016-09-02 13:24:55.175990265 +0200
@@ -0,0 +1,12 @@
+// PR sanitizer/77396
+// { dg-do run }
+// { dg-set-target-env-var ASAN_OPTIONS "check_initialization_order=true" }
+
+static int a = 0; 
+static int b = a; 
+
+int
+main ()
+{
+  return 0;
+}


        Jakub

Reply via email to