]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add no_sanitize_coverage attribute.
authorMartin Liska <mliska@suse.cz>
Thu, 20 May 2021 07:32:29 +0000 (09:32 +0200)
committerMartin Liska <mliska@suse.cz>
Tue, 25 May 2021 12:56:28 +0000 (14:56 +0200)
gcc/ChangeLog:

* asan.h (sanitize_coverage_p): New function.
* doc/extend.texi: Document it.
* fold-const.c (fold_range_test): Use sanitize_flags_p
instead of flag_sanitize_coverage.
(fold_truth_andor): Likewise.
* sancov.c: Likewise.
* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
* ipa-inline.c (sanitize_attrs_match_for_inline_p): Handle
-fsanitize-coverage when inlining.

gcc/c-family/ChangeLog:

* c-attribs.c (handle_no_sanitize_coverage_attribute): New.

gcc/testsuite/ChangeLog:

* gcc.dg/sancov/attribute.c: New test.

gcc/asan.h
gcc/c-family/c-attribs.c
gcc/doc/extend.texi
gcc/fold-const.c
gcc/ipa-inline.c
gcc/sancov.c
gcc/testsuite/gcc.dg/sancov/attribute.c [new file with mode: 0644]
gcc/tree-ssa-ifcombine.c

index f110f1db563aa2cb2f962a275312c06c38340a00..8c0b2baf1701b8829d149b68bd9fe3cb5070ebf6 100644 (file)
@@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl)
   return result_flags;
 }
 
+/* Return true when coverage sanitization should happend for FN function.  */
+
+static inline bool
+sanitize_coverage_p (const_tree fn = current_function_decl)
+{
+  return (flag_sanitize_coverage
+         && lookup_attribute ("no_sanitize_coverage",
+                              DECL_ATTRIBUTES (fn)) == NULL_TREE);
+}
+
 #endif /* TREE_ASAN */
index ccf9e4ccf0b9c44091d49a98d04a6fec59791b92..671b27c3200596b6b330f752f56c09b724c128b9 100644 (file)
@@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
                                                         int, bool *);
 static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
                                                    bool *);
+static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int,
+                                                  bool *);
 static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
                                                 bool *);
 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
@@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_no_sanitize_thread_attribute, NULL },
   { "no_sanitize_undefined",  0, 0, true, false, false, false,
                              handle_no_sanitize_undefined_attribute, NULL },
+  { "no_sanitize_coverage",   0, 0, true, false, false, false,
+                             handle_no_sanitize_coverage_attribute, NULL },
   { "asan odr indicator",     0, 0, true, false, false, false,
                              handle_asan_odr_indicator_attribute, NULL },
   { "warning",               1, 1, true,  false, false, false,
@@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
   return NULL_TREE;
 }
 
+/* Handle a "no_sanitize_coverage" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int,
+                                      bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle an "asan odr indicator" attribute; arguments as in
    struct attribute_spec.handler.  */
 
index 826804e61493ca21fbef7d157028c6af4c39b633..3ddeb0dee3a631ad6f2bfb1f9b880010cfa69064 100644 (file)
@@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used
 to inform the compiler that it should not check for undefined behavior
 in the function when compiling with the @option{-fsanitize=undefined} option.
 
+@item no_sanitize_coverage
+@cindex @code{no_sanitize_coverage} function attribute
+The @code{no_sanitize_coverage} attribute on functions is used
+to inform the compiler that it should not do coverage-guided
+fuzzing code instrumentation (@option{-fsanitize-coverage}).
+
 @item no_split_stack
 @cindex @code{no_split_stack} function attribute
 @opindex fsplit-stack
index 3be9c15e6b243ea695fe505681fe840ef5d39007..d088187a05750c80362631807055edc80ab247df 100644 (file)
@@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type,
     logical_op_non_short_circuit
       = param_logical_op_non_short_circuit;
   if (logical_op_non_short_circuit
-      && !flag_sanitize_coverage
+      && !sanitize_coverage_p ()
       && lhs != 0 && rhs != 0
       && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
       && operand_equal_p (lhs, rhs, 0))
@@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type,
     logical_op_non_short_circuit
       = param_logical_op_non_short_circuit;
   if (logical_op_non_short_circuit
-      && !flag_sanitize_coverage
+      && !sanitize_coverage_p ()
       && (code == TRUTH_AND_EXPR
           || code == TRUTH_ANDIF_EXPR
           || code == TRUTH_OR_EXPR
index f15c4828958908a1dd5c906c896dfa1d75cc943f..9d896beb2ac162dea493b1a6924b0fd17df8bd87 100644 (file)
@@ -283,6 +283,9 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee)
        != sanitize_flags_p (codes[i], callee))
       return false;
 
+  if (sanitize_coverage_p (caller) != sanitize_coverage_p (callee))
+    return false;
+
   return true;
 }
 
index d656c37cae9b04fcd1190d0b1b87e3f0ac12eae9..9cfbd425def3ac91b3e424674474e8a1e8e525db 100644 (file)
@@ -313,9 +313,9 @@ public:
     return new pass_sancov<O0> (m_ctxt);
   }
   virtual bool
-  gate (function *)
+  gate (function *fun)
   {
-    return flag_sanitize_coverage && (!O0 || !optimize);
+    return sanitize_coverage_p (fun->decl) && (!O0 || !optimize);
   }
   virtual unsigned int
   execute (function *fun)
diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c
new file mode 100644 (file)
index 0000000..7cfa913
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */
+
+void foo(void)
+{
+}
+
+void
+__attribute__((no_sanitize_coverage))
+bar(void)
+{
+}
+
+static void inline
+__attribute__((always_inline))
+inline_fn(void)
+{
+}
+
+void
+__attribute__((no_sanitize_coverage))
+baz(void)
+{
+  inline_fn();
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */
index 836a12d6b80ed457178ac8031924e961bf1e5955..f93e04aa4dfcc2e2a9eef28f3679b2a3ab4c6540 100644 (file)
@@ -40,6 +40,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimplify-me.h"
 #include "tree-cfg.h"
 #include "tree-ssa.h"
+#include "attribs.h"
+#include "asan.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
          if (param_logical_op_non_short_circuit != -1)
            logical_op_non_short_circuit
              = param_logical_op_non_short_circuit;
-         if (!logical_op_non_short_circuit || flag_sanitize_coverage)
+         if (!logical_op_non_short_circuit || sanitize_coverage_p ())
            return false;
          /* Only do this optimization if the inner bb contains only the conditional. */
          if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb)))