Commit 5cc6c41c by Martin Liska Committed by Martin Liska

Fix handling of -fsanitize-recover* options.

	* common.opt: Exclude SANITIZE_UNREACHABLE and SANITIZE_RETURN
	from default sanitize recover values.
	* doc/invoke.texi: Fix documentation related to -fsanitize=leak,
	-fsanitize=address, -fsanitize=thread and -fsanitize-recover.
	* flag-types.h: Replace couple of 1 << x to 1UL << x, make it
	consistent.
	* opts.c (finish_options): Do a generic loop over options
	that can be recovered.
	(parse_sanitizer_options): Exclude SANITIZE_UNREACHABLE and
	SANITIZE_RETURN.
	(common_handle_option): Likewise.
	* opts.h: Declare can_recover to sanitizer_opts_s.
	* c-c++-common/ubsan/sanitize-recover-1.c: New test.
	* c-c++-common/ubsan/sanitize-recover-2.c: New test.
	* c-c++-common/ubsan/sanitize-recover-3.c: New test.
	* c-c++-common/ubsan/sanitize-recover-4.c: New test.
	* c-c++-common/ubsan/sanitize-recover-5.c: New test.
	* c-c++-common/ubsan/sanitize-recover-6.c: New test.
	* c-c++-common/ubsan/sanitize-recover-7.c: New test.
	* c-c++-common/ubsan/sanitize-recover-8.c: New test.
	* c-c++-common/ubsan/sanitize-recover-9.c: New test.

From-SVN: r240491
parent 759a6472
2016-09-26 Martin Liska <mliska@suse.cz>
* common.opt: Exclude SANITIZE_UNREACHABLE and SANITIZE_RETURN
from default sanitize recover values.
* doc/invoke.texi: Fix documentation related to -fsanitize=leak,
-fsanitize=address, -fsanitize=thread and -fsanitize-recover.
* flag-types.h: Replace couple of 1 << x to 1UL << x, make it
consistent.
* opts.c (finish_options): Do a generic loop over options
that can be recovered.
(parse_sanitizer_options): Exclude SANITIZE_UNREACHABLE and
SANITIZE_RETURN.
(common_handle_option): Likewise.
* opts.h: Declare can_recover to sanitizer_opts_s.
2016-09-26 Andre Vieira <andre.simoesdiasvieira@arm.com> 2016-09-26 Andre Vieira <andre.simoesdiasvieira@arm.com>
* target.def(elf_flags_numeric): Change documentation to * target.def(elf_flags_numeric): Change documentation to
......
...@@ -228,7 +228,7 @@ unsigned int flag_sanitize ...@@ -228,7 +228,7 @@ unsigned int flag_sanitize
; What sanitizers should recover from errors ; What sanitizers should recover from errors
Variable Variable
unsigned int flag_sanitize_recover = SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT | SANITIZE_KERNEL_ADDRESS unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
fsanitize-coverage=trace-pc fsanitize-coverage=trace-pc
Common Report Var(flag_sanitize_coverage) Common Report Var(flag_sanitize_coverage)
......
...@@ -10255,6 +10255,7 @@ more details. The run-time behavior can be influenced using the ...@@ -10255,6 +10255,7 @@ more details. The run-time behavior can be influenced using the
the available options are shown at startup of the instrumented program. See the available options are shown at startup of the instrumented program. See
@url{https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags} @url{https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags}
for a list of supported options. for a list of supported options.
The option can't be combined with @option{-fsanitize=thread}.
@item -fsanitize=kernel-address @item -fsanitize=kernel-address
@opindex fsanitize=kernel-address @opindex fsanitize=kernel-address
...@@ -10270,17 +10271,19 @@ details. The run-time behavior can be influenced using the @env{TSAN_OPTIONS} ...@@ -10270,17 +10271,19 @@ details. The run-time behavior can be influenced using the @env{TSAN_OPTIONS}
environment variable; see environment variable; see
@url{https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags} for a list of @url{https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags} for a list of
supported options. supported options.
The option can't be combined with @option{-fsanitize=address}
and/or @option{-fsanitize=leak}.
@item -fsanitize=leak @item -fsanitize=leak
@opindex fsanitize=leak @opindex fsanitize=leak
Enable LeakSanitizer, a memory leak detector. Enable LeakSanitizer, a memory leak detector.
This option only matters for linking of executables and if neither This option only matters for linking of executables and
@option{-fsanitize=address} nor @option{-fsanitize=thread} is used. In that the executable is linked against a library that overrides @code{malloc}
case the executable is linked against a library that overrides @code{malloc}
and other allocator functions. See and other allocator functions. See
@uref{https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer} for more @uref{https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer} for more
details. The run-time behavior can be influenced using the details. The run-time behavior can be influenced using the
@env{LSAN_OPTIONS} environment variable. @env{LSAN_OPTIONS} environment variable.
The option can't be combined with @option{-fsanitize=thread}.
@item -fsanitize=undefined @item -fsanitize=undefined
@opindex fsanitize=undefined @opindex fsanitize=undefined
...@@ -10454,6 +10457,7 @@ and program then exits with a non-zero exit code. ...@@ -10454,6 +10457,7 @@ and program then exits with a non-zero exit code.
Currently this feature only works for @option{-fsanitize=undefined} (and its suboptions Currently this feature only works for @option{-fsanitize=undefined} (and its suboptions
except for @option{-fsanitize=unreachable} and @option{-fsanitize=return}), except for @option{-fsanitize=unreachable} and @option{-fsanitize=return}),
@option{-fsanitize=float-cast-overflow}, @option{-fsanitize=float-divide-by-zero}, @option{-fsanitize=float-cast-overflow}, @option{-fsanitize=float-divide-by-zero},
@option{-fsanitize=bounds-strict},
@option{-fsanitize=kernel-address} and @option{-fsanitize=address}. @option{-fsanitize=kernel-address} and @option{-fsanitize=address}.
For these sanitizers error recovery is turned on by default, except @option{-fsanitize=address}, For these sanitizers error recovery is turned on by default, except @option{-fsanitize=address},
for which this feature is experimental. for which this feature is experimental.
...@@ -10470,12 +10474,12 @@ setting the @code{halt_on_error} flag in the corresponding environment variable. ...@@ -10470,12 +10474,12 @@ setting the @code{halt_on_error} flag in the corresponding environment variable.
Syntax without explicit @var{opts} parameter is deprecated. It is equivalent to Syntax without explicit @var{opts} parameter is deprecated. It is equivalent to
@smallexample @smallexample
-fsanitize-recover=undefined,float-cast-overflow,float-divide-by-zero -fsanitize-recover=undefined,float-cast-overflow,float-divide-by-zero,bounds-strict
@end smallexample @end smallexample
@noindent @noindent
Similarly @option{-fno-sanitize-recover} is equivalent to Similarly @option{-fno-sanitize-recover} is equivalent to
@smallexample @smallexample
-fno-sanitize-recover=undefined,float-cast-overflow,float-divide-by-zero -fno-sanitize-recover=undefined,float-cast-overflow,float-divide-by-zero,bounds-strict
@end smallexample @end smallexample
@item -fsanitize-undefined-trap-on-error @item -fsanitize-undefined-trap-on-error
......
...@@ -203,25 +203,25 @@ enum vect_cost_model { ...@@ -203,25 +203,25 @@ enum vect_cost_model {
/* Different instrumentation modes. */ /* Different instrumentation modes. */
enum sanitize_code { enum sanitize_code {
/* AddressSanitizer. */ /* AddressSanitizer. */
SANITIZE_ADDRESS = 1 << 0, SANITIZE_ADDRESS = 1UL << 0,
SANITIZE_USER_ADDRESS = 1 << 1, SANITIZE_USER_ADDRESS = 1UL << 1,
SANITIZE_KERNEL_ADDRESS = 1 << 2, SANITIZE_KERNEL_ADDRESS = 1UL << 2,
/* ThreadSanitizer. */ /* ThreadSanitizer. */
SANITIZE_THREAD = 1 << 3, SANITIZE_THREAD = 1UL << 3,
/* LeakSanitizer. */ /* LeakSanitizer. */
SANITIZE_LEAK = 1 << 4, SANITIZE_LEAK = 1UL << 4,
/* UndefinedBehaviorSanitizer. */ /* UndefinedBehaviorSanitizer. */
SANITIZE_SHIFT = 1 << 5, SANITIZE_SHIFT = 1UL << 5,
SANITIZE_DIVIDE = 1 << 6, SANITIZE_DIVIDE = 1UL << 6,
SANITIZE_UNREACHABLE = 1 << 7, SANITIZE_UNREACHABLE = 1UL << 7,
SANITIZE_VLA = 1 << 8, SANITIZE_VLA = 1UL << 8,
SANITIZE_NULL = 1 << 9, SANITIZE_NULL = 1UL << 9,
SANITIZE_RETURN = 1 << 10, SANITIZE_RETURN = 1UL << 10,
SANITIZE_SI_OVERFLOW = 1 << 11, SANITIZE_SI_OVERFLOW = 1UL << 11,
SANITIZE_BOOL = 1 << 12, SANITIZE_BOOL = 1UL << 12,
SANITIZE_ENUM = 1 << 13, SANITIZE_ENUM = 1UL << 13,
SANITIZE_FLOAT_DIVIDE = 1 << 14, SANITIZE_FLOAT_DIVIDE = 1UL << 14,
SANITIZE_FLOAT_CAST = 1 << 15, SANITIZE_FLOAT_CAST = 1UL << 15,
SANITIZE_BOUNDS = 1UL << 16, SANITIZE_BOUNDS = 1UL << 16,
SANITIZE_ALIGNMENT = 1UL << 17, SANITIZE_ALIGNMENT = 1UL << 17,
SANITIZE_NONNULL_ATTRIBUTE = 1UL << 18, SANITIZE_NONNULL_ATTRIBUTE = 1UL << 18,
......
...@@ -941,7 +941,6 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, ...@@ -941,7 +941,6 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
opts->x_debug_generate_pub_sections = 2; opts->x_debug_generate_pub_sections = 2;
/* Userspace and kernel ASan conflict with each other. */ /* Userspace and kernel ASan conflict with each other. */
if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
&& (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)) && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
error_at (loc, error_at (loc,
...@@ -949,20 +948,23 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, ...@@ -949,20 +948,23 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
"-fsanitize=kernel-address"); "-fsanitize=kernel-address");
/* And with TSan. */ /* And with TSan. */
if ((opts->x_flag_sanitize & SANITIZE_ADDRESS) if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
&& (opts->x_flag_sanitize & SANITIZE_THREAD)) && (opts->x_flag_sanitize & SANITIZE_THREAD))
error_at (loc, error_at (loc,
"-fsanitize=address and -fsanitize=kernel-address " "-fsanitize=address and -fsanitize=kernel-address "
"are incompatible with -fsanitize=thread"); "are incompatible with -fsanitize=thread");
/* Error recovery is not allowed for LSan and TSan. */ if ((opts->x_flag_sanitize & SANITIZE_LEAK)
&& (opts->x_flag_sanitize & SANITIZE_THREAD))
if (opts->x_flag_sanitize_recover & SANITIZE_THREAD) error_at (loc,
error_at (loc, "-fsanitize-recover=thread is not supported"); "-fsanitize=leak is incompatible with -fsanitize=thread");
if (opts->x_flag_sanitize_recover & SANITIZE_LEAK) /* Check error recovery for -fsanitize-recover option. */
error_at (loc, "-fsanitize-recover=leak is not supported"); for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
&& !sanitizer_opts[i].can_recover)
error_at (loc, "-fsanitize-recover=%s is not supported",
sanitizer_opts[i].name);
/* When instrumenting the pointers, we don't want to remove /* When instrumenting the pointers, we don't want to remove
the null pointer checks. */ the null pointer checks. */
...@@ -1448,33 +1450,36 @@ enable_fdo_optimizations (struct gcc_options *opts, ...@@ -1448,33 +1450,36 @@ enable_fdo_optimizations (struct gcc_options *opts,
/* -f{,no-}sanitize{,-recover}= suboptions. */ /* -f{,no-}sanitize{,-recover}= suboptions. */
const struct sanitizer_opts_s sanitizer_opts[] = const struct sanitizer_opts_s sanitizer_opts[] =
{ {
#define SANITIZER_OPT(name, flags) { #name, flags, sizeof #name - 1 } #define SANITIZER_OPT(name, flags, recover) \
SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), { #name, flags, sizeof #name - 1, recover }
SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS), SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS, true),
SANITIZER_OPT (thread, SANITIZE_THREAD), SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS,
SANITIZER_OPT (leak, SANITIZE_LEAK), true),
SANITIZER_OPT (shift, SANITIZE_SHIFT), SANITIZER_OPT (thread, SANITIZE_THREAD, false),
SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE), SANITIZER_OPT (leak, SANITIZE_LEAK, false),
SANITIZER_OPT (undefined, SANITIZE_UNDEFINED), SANITIZER_OPT (shift, SANITIZE_SHIFT, true),
SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE), SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true),
SANITIZER_OPT (vla-bound, SANITIZE_VLA), SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true),
SANITIZER_OPT (return, SANITIZE_RETURN), SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false),
SANITIZER_OPT (null, SANITIZE_NULL), SANITIZER_OPT (vla-bound, SANITIZE_VLA, true),
SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW), SANITIZER_OPT (return, SANITIZE_RETURN, false),
SANITIZER_OPT (bool, SANITIZE_BOOL), SANITIZER_OPT (null, SANITIZE_NULL, true),
SANITIZER_OPT (enum, SANITIZE_ENUM), SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true),
SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE), SANITIZER_OPT (bool, SANITIZE_BOOL, true),
SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST), SANITIZER_OPT (enum, SANITIZE_ENUM, true),
SANITIZER_OPT (bounds, SANITIZE_BOUNDS), SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true),
SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT), SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true),
SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT), SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true),
SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE), SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true),
SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE), SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true),
SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE), SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true),
SANITIZER_OPT (vptr, SANITIZE_VPTR), SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
SANITIZER_OPT (all, ~0U), true),
SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true),
SANITIZER_OPT (vptr, SANITIZE_VPTR, true),
SANITIZER_OPT (all, ~0U, true),
#undef SANITIZER_OPT #undef SANITIZER_OPT
{ NULL, 0U, 0UL } { NULL, 0U, 0UL, false }
}; };
/* Parse comma separated sanitizer suboptions from P for option SCODE, /* Parse comma separated sanitizer suboptions from P for option SCODE,
...@@ -1516,11 +1521,20 @@ parse_sanitizer_options (const char *p, location_t loc, int scode, ...@@ -1516,11 +1521,20 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
error_at (loc, "-fsanitize=all option is not valid"); error_at (loc, "-fsanitize=all option is not valid");
} }
else else
flags |= ~(SANITIZE_USER_ADDRESS | SANITIZE_THREAD flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
| SANITIZE_LEAK); | SANITIZE_UNREACHABLE | SANITIZE_RETURN);
} }
else if (value) else if (value)
flags |= sanitizer_opts[i].flag; {
/* Do not enable -fsanitize-recover=unreachable and
-fsanitize-recover=return if -fsanitize-recover=undefined
is selected. */
if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
flags |= (SANITIZE_UNDEFINED
& ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
else
flags |= sanitizer_opts[i].flag;
}
else else
flags &= ~sanitizer_opts[i].flag; flags &= ~sanitizer_opts[i].flag;
found = true; found = true;
...@@ -1770,7 +1784,8 @@ common_handle_option (struct gcc_options *opts, ...@@ -1770,7 +1784,8 @@ common_handle_option (struct gcc_options *opts,
case OPT_fsanitize_recover: case OPT_fsanitize_recover:
if (value) if (value)
opts->x_flag_sanitize_recover opts->x_flag_sanitize_recover
|= SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT; |= (SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT)
& ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
else else
opts->x_flag_sanitize_recover opts->x_flag_sanitize_recover
&= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT); &= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT);
......
...@@ -414,6 +414,7 @@ extern const struct sanitizer_opts_s ...@@ -414,6 +414,7 @@ extern const struct sanitizer_opts_s
const char *const name; const char *const name;
unsigned int flag; unsigned int flag;
size_t len; size_t len;
bool can_recover;
} sanitizer_opts[]; } sanitizer_opts[];
extern void add_misspelling_candidates (auto_vec<char *> *candidates, extern void add_misspelling_candidates (auto_vec<char *> *candidates,
......
2016-09-26 Martin Liska <mliska@suse.cz>
* c-c++-common/ubsan/sanitize-recover-1.c: New test.
* c-c++-common/ubsan/sanitize-recover-2.c: New test.
* c-c++-common/ubsan/sanitize-recover-3.c: New test.
* c-c++-common/ubsan/sanitize-recover-4.c: New test.
* c-c++-common/ubsan/sanitize-recover-5.c: New test.
* c-c++-common/ubsan/sanitize-recover-6.c: New test.
* c-c++-common/ubsan/sanitize-recover-7.c: New test.
* c-c++-common/ubsan/sanitize-recover-8.c: New test.
* c-c++-common/ubsan/sanitize-recover-9.c: New test.
2016-09-26 Marek Polacek <polacek@redhat.com> 2016-09-26 Marek Polacek <polacek@redhat.com>
PR c/7652 PR c/7652
......
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=unreachable" } */
int i;
/* { dg-error "-fsanitize-recover=unreachable is not supported" "" { target *-*-* } 0 } */
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=return" } */
int i;
/* { dg-error "-fsanitize-recover=return is not supported" "" { target *-*-* } 0 } */
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=all" } */
int i;
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=undefined" } */
int i;
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=undefined,unreachable" } */
int i;
/* { dg-error "-fsanitize-recover=unreachable is not supported" "" { target *-*-* } 0 } */
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=undefined,unreachable -fno-sanitize-recover=unreachable" } */
int i;
/* { dg-do compile } */
/* { dg-options "-fsanitize=address -fsanitize=thread" } */
int i;
/* { dg-error "-fsanitize=address and -fsanitize=kernel-address are incompatible with -fsanitize=thread" "" { target *-*-* } 0 } */
/* { dg-do compile } */
/* { dg-options "-fsanitize=leak -fsanitize=thread" } */
int i;
/* { dg-error "-fsanitize=leak is incompatible with -fsanitize=thread" "" { target *-*-* } 0 } */
/* { dg-do compile } */
/* { dg-options "-fsanitize-recover=unreachable -fsanitize-recover=undefined" } */
int i;
/* { dg-error "-fsanitize-recover=unreachable is not supported" "" { target *-*-* } 0 } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment