On Thu, 20 May 2021 at 10:33, Martin Liška <mli...@suse.cz> wrote: > Hello. > > The patch implements one missing attribute which can be used for per-function > disabling of coverage sanitization. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Thanks for implementing this so quickly. One thing I just have to double check, is if this works with always_inline (not instrumented if inlined into no_sanitize), and inline (not inlined if inline fn is no_sanitize_coverage). Just like the other no_sanitize* do. The test doesn't mention them. Thanks, -- Marco > Ready to be installed? > Thanks, > Martin > > 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. > > 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 | 10 ++++++++++ > gcc/c-family/c-attribs.c | 20 ++++++++++++++++++++ > gcc/doc/extend.texi | 6 ++++++ > gcc/fold-const.c | 4 ++-- > gcc/sancov.c | 4 ++-- > gcc/testsuite/gcc.dg/sancov/attribute.c | 15 +++++++++++++++ > gcc/tree-ssa-ifcombine.c | 4 +++- > 7 files changed, 58 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c > > diff --git a/gcc/asan.h b/gcc/asan.h > index f110f1db563..8c0b2baf170 100644 > --- a/gcc/asan.h > +++ b/gcc/asan.h > @@ -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 */ > diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c > index ccf9e4ccf0b..671b27c3200 100644 > --- a/gcc/c-family/c-attribs.c > +++ b/gcc/c-family/c-attribs.c > @@ -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. */ > > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 826804e6149..3ddeb0dee3a 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -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 > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > index 3be9c15e6b2..d088187a057 100644 > --- a/gcc/fold-const.c > +++ b/gcc/fold-const.c > @@ -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 > diff --git a/gcc/sancov.c b/gcc/sancov.c > index d656c37cae9..9cfbd425def 100644 > --- a/gcc/sancov.c > +++ b/gcc/sancov.c > @@ -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 > index 00000000000..bf6dbd4bae7 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ > + > +void foo(void) > +{ > +} > + > +void > +__attribute__((no_sanitize_coverage)) > +bar(void) > +{ > +} > + > + > +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc > \\(\\)" 1 "optimized" } } */ > diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c > index 836a12d6b80..f93e04aa4df 100644 > --- a/gcc/tree-ssa-ifcombine.c > +++ b/gcc/tree-ssa-ifcombine.c > @@ -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))) > -- > 2.31.1 >