gcc.c (sanitize_spec_function): Handle SANITIZE_FLOAT_DIVIDE.

* gcc.c (sanitize_spec_function): Handle SANITIZE_FLOAT_DIVIDE.
	* builtins.def: Initialize builtins even for SANITIZE_FLOAT_DIVIDE.
	* flag-types.h (enum sanitize_code): Add SANITIZE_FLOAT_DIVIDE.
	* opts.c (common_handle_option): Add -fsanitize=float-divide-by-zero.
c-family/
	* c-ubsan.c (ubsan_instrument_division): Handle REAL_TYPEs.  Perform
	INT_MIN / -1 sanitization only for integer types.
c/
	* c-typeck.c (build_binary_op): Call ubsan_instrument_division
	also when SANITIZE_FLOAT_DIVIDE is on.
cp/
	* typeck.c (cp_build_binary_op): Call ubsan_instrument_division
	even when SANITIZE_FLOAT_DIVIDE is on.  Set doing_div_or_mod even
	for non-integer types.
testsuite/
	* c-c++-common/ubsan/div-by-zero-5.c: Fix formatting.
	* c-c++-common/ubsan/float-div-by-zero-1.c: New test.

From-SVN: r209927
This commit is contained in:
Marek Polacek 2014-04-30 07:34:43 +00:00 committed by Marek Polacek
parent 8337d1db71
commit f8ed5150c3
14 changed files with 82 additions and 20 deletions

View File

@ -1,3 +1,10 @@
2014-04-30 Marek Polacek <polacek@redhat.com>
* gcc.c (sanitize_spec_function): Handle SANITIZE_FLOAT_DIVIDE.
* builtins.def: Initialize builtins even for SANITIZE_FLOAT_DIVIDE.
* flag-types.h (enum sanitize_code): Add SANITIZE_FLOAT_DIVIDE.
* opts.c (common_handle_option): Add -fsanitize=float-divide-by-zero.
2014-04-29 Alan Lawrence <alan.lawrence@arm.com>
* config/aarch64/arm_neon.h (vzip1_f32, vzip1_p8, vzip1_p16, vzip1_s8,

View File

@ -176,7 +176,7 @@ along with GCC; see the file COPYING3. If not see
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
true, true, true, ATTRS, true, \
(flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \
| SANITIZE_UNDEFINED)))
| SANITIZE_UNDEFINED | SANITIZE_FLOAT_DIVIDE)))
#undef DEF_CILKPLUS_BUILTIN
#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \

View File

@ -1,3 +1,8 @@
2014-04-30 Marek Polacek <polacek@redhat.com>
* c-ubsan.c (ubsan_instrument_division): Handle REAL_TYPEs. Perform
INT_MIN / -1 sanitization only for integer types.
2014-04-25 Marek Polacek <polacek@redhat.com>
PR c/18079

View File

@ -46,15 +46,21 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
== TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
/* TODO: REAL_TYPE is not supported yet. */
if (TREE_CODE (type) != INTEGER_TYPE)
if (TREE_CODE (type) == INTEGER_TYPE
&& (flag_sanitize & SANITIZE_DIVIDE))
t = fold_build2 (EQ_EXPR, boolean_type_node,
op1, build_int_cst (type, 0));
else if (TREE_CODE (type) == REAL_TYPE
&& (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
t = fold_build2 (EQ_EXPR, boolean_type_node,
op1, build_real (type, dconst0));
else
return NULL_TREE;
t = fold_build2 (EQ_EXPR, boolean_type_node,
op1, build_int_cst (type, 0));
/* We check INT_MIN / -1 only for signed types. */
if (!TYPE_UNSIGNED (type))
if (TREE_CODE (type) == INTEGER_TYPE
&& (flag_sanitize & SANITIZE_DIVIDE)
&& !TYPE_UNSIGNED (type))
{
tree x;
tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,

View File

@ -1,3 +1,8 @@
2014-04-30 Marek Polacek <polacek@redhat.com>
* c-typeck.c (build_binary_op): Call ubsan_instrument_division
also when SANITIZE_FLOAT_DIVIDE is on.
2014-04-30 Marek Polacek <polacek@redhat.com>
PR c/60139

View File

@ -10997,7 +10997,8 @@ build_binary_op (location_t location, enum tree_code code,
return error_mark_node;
}
if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE))
if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE
| SANITIZE_FLOAT_DIVIDE))
&& current_function_decl != 0
&& !lookup_attribute ("no_sanitize_undefined",
DECL_ATTRIBUTES (current_function_decl))
@ -11008,7 +11009,8 @@ build_binary_op (location_t location, enum tree_code code,
op1 = c_save_expr (op1);
op0 = c_fully_fold (op0, false, NULL);
op1 = c_fully_fold (op1, false, NULL);
if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE))
if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE
| SANITIZE_FLOAT_DIVIDE)))
instrument_expr = ubsan_instrument_division (location, op0, op1);
else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT))
instrument_expr = ubsan_instrument_shift (location, code, op0, op1);

View File

@ -1,3 +1,9 @@
2014-04-30 Marek Polacek <polacek@redhat.com>
* typeck.c (cp_build_binary_op): Call ubsan_instrument_division
even when SANITIZE_FLOAT_DIVIDE is on. Set doing_div_or_mod even
for non-integer types.
2014-04-29 Jason Merrill <jason@redhat.com>
DR 1351

View File

@ -4110,10 +4110,7 @@ cp_build_binary_op (location_t location,
enum tree_code tcode0 = code0, tcode1 = code1;
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
cop1 = maybe_constant_value (cop1);
if (tcode0 == INTEGER_TYPE)
doing_div_or_mod = true;
doing_div_or_mod = true;
warn_for_div_by_zero (location, cop1);
if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
@ -4153,9 +4150,7 @@ cp_build_binary_op (location_t location,
{
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
cop1 = maybe_constant_value (cop1);
if (code0 == INTEGER_TYPE)
doing_div_or_mod = true;
doing_div_or_mod = true;
warn_for_div_by_zero (location, cop1);
}
@ -4902,7 +4897,8 @@ cp_build_binary_op (location_t location,
if (build_type == NULL_TREE)
build_type = result_type;
if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE))
if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE
| SANITIZE_FLOAT_DIVIDE))
&& !processing_template_decl
&& current_function_decl != 0
&& !lookup_attribute ("no_sanitize_undefined",
@ -4916,7 +4912,8 @@ cp_build_binary_op (location_t location,
tf_none));
op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1,
tf_none));
if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE))
if (doing_div_or_mod && (flag_sanitize & (SANITIZE_DIVIDE
| SANITIZE_FLOAT_DIVIDE)))
{
/* For diagnostics we want to use the promoted types without
shorten_binary_op. So convert the arguments to the

View File

@ -228,6 +228,7 @@ enum sanitize_code {
SANITIZE_SI_OVERFLOW = 1 << 9,
SANITIZE_BOOL = 1 << 10,
SANITIZE_ENUM = 1 << 11,
SANITIZE_FLOAT_DIVIDE = 1 << 12,
SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
| SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
| SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM

View File

@ -8170,7 +8170,7 @@ sanitize_spec_function (int argc, const char **argv)
if (strcmp (argv[0], "thread") == 0)
return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
if (strcmp (argv[0], "undefined") == 0)
return ((flag_sanitize & SANITIZE_UNDEFINED)
return ((flag_sanitize & (SANITIZE_UNDEFINED | SANITIZE_FLOAT_DIVIDE))
&& !flag_sanitize_undefined_trap_on_error) ? "" : NULL;
if (strcmp (argv[0], "leak") == 0)
return ((flag_sanitize

View File

@ -1461,6 +1461,8 @@ common_handle_option (struct gcc_options *opts,
sizeof "signed-integer-overflow" -1 },
{ "bool", SANITIZE_BOOL, sizeof "bool" - 1 },
{ "enum", SANITIZE_ENUM, sizeof "enum" - 1 },
{ "float-divide-by-zero", SANITIZE_FLOAT_DIVIDE,
sizeof "float-divide-by-zero" - 1 },
{ NULL, 0, 0 }
};
const char *comma;

View File

@ -1,3 +1,8 @@
2014-04-30 Marek Polacek <polacek@redhat.com>
* c-c++-common/ubsan/div-by-zero-5.c: Fix formatting.
* c-c++-common/ubsan/float-div-by-zero-1.c: New test.
2014-04-30 Marek Polacek <polacek@redhat.com>
PR c/60139

View File

@ -1,4 +1,4 @@
/* { dg-do compile} */
/* { dg-do compile } */
/* { dg-options "-fsanitize=integer-divide-by-zero" } */
void

View File

@ -0,0 +1,26 @@
/* { dg-do run } */
/* { dg-options "-fsanitize=float-divide-by-zero" } */
int
main (void)
{
volatile float a = 1.3f;
volatile double b = 0.0;
volatile int c = 4;
volatile float res;
res = a / b;
res = a / 0.0;
res = 2.7f / b;
res = 3.6 / (b = 0.0, b);
res = c / b;
res = b / c;
return 0;
}
/* { dg-output "division by zero\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*" } */