Commit f8ed5150 by Marek Polacek Committed by Marek Polacek

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
parent 8337d1db
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> 2014-04-29 Alan Lawrence <alan.lawrence@arm.com>
* config/aarch64/arm_neon.h (vzip1_f32, vzip1_p8, vzip1_p16, vzip1_s8, * config/aarch64/arm_neon.h (vzip1_f32, vzip1_p8, vzip1_p16, vzip1_s8,
......
...@@ -176,7 +176,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -176,7 +176,7 @@ along with GCC; see the file COPYING3. If not see
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
true, true, true, ATTRS, true, \ true, true, true, ATTRS, true, \
(flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \ (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \
| SANITIZE_UNDEFINED))) | SANITIZE_UNDEFINED | SANITIZE_FLOAT_DIVIDE)))
#undef DEF_CILKPLUS_BUILTIN #undef DEF_CILKPLUS_BUILTIN
#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ #define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
......
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> 2014-04-25 Marek Polacek <polacek@redhat.com>
PR c/18079 PR c/18079
......
...@@ -46,15 +46,21 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) ...@@ -46,15 +46,21 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0)) gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
== TYPE_MAIN_VARIANT (TREE_TYPE (op1))); == 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; 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. */ /* 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; tree x;
tt = fold_build2 (EQ_EXPR, boolean_type_node, op1, tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
......
2014-04-30 Marek Polacek <polacek@redhat.com> 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 PR c/60139
* c-typeck.c (output_init_element): Pass OPT_Wpedantic to pedwarn * c-typeck.c (output_init_element): Pass OPT_Wpedantic to pedwarn
and pedwarn_init. Use loc insted of input_location. and pedwarn_init. Use loc insted of input_location.
......
...@@ -10997,7 +10997,8 @@ build_binary_op (location_t location, enum tree_code code, ...@@ -10997,7 +10997,8 @@ build_binary_op (location_t location, enum tree_code code,
return error_mark_node; 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 && current_function_decl != 0
&& !lookup_attribute ("no_sanitize_undefined", && !lookup_attribute ("no_sanitize_undefined",
DECL_ATTRIBUTES (current_function_decl)) DECL_ATTRIBUTES (current_function_decl))
...@@ -11008,7 +11009,8 @@ build_binary_op (location_t location, enum tree_code code, ...@@ -11008,7 +11009,8 @@ build_binary_op (location_t location, enum tree_code code,
op1 = c_save_expr (op1); op1 = c_save_expr (op1);
op0 = c_fully_fold (op0, false, NULL); op0 = c_fully_fold (op0, false, NULL);
op1 = c_fully_fold (op1, 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); instrument_expr = ubsan_instrument_division (location, op0, op1);
else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT)) else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT))
instrument_expr = ubsan_instrument_shift (location, code, op0, op1); instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
......
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> 2014-04-29 Jason Merrill <jason@redhat.com>
DR 1351 DR 1351
......
...@@ -4110,10 +4110,7 @@ cp_build_binary_op (location_t location, ...@@ -4110,10 +4110,7 @@ cp_build_binary_op (location_t location,
enum tree_code tcode0 = code0, tcode1 = code1; enum tree_code tcode0 = code0, tcode1 = code1;
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
cop1 = maybe_constant_value (cop1); cop1 = maybe_constant_value (cop1);
doing_div_or_mod = true;
if (tcode0 == INTEGER_TYPE)
doing_div_or_mod = true;
warn_for_div_by_zero (location, cop1); warn_for_div_by_zero (location, cop1);
if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE) if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
...@@ -4153,9 +4150,7 @@ cp_build_binary_op (location_t location, ...@@ -4153,9 +4150,7 @@ cp_build_binary_op (location_t location,
{ {
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
cop1 = maybe_constant_value (cop1); cop1 = maybe_constant_value (cop1);
doing_div_or_mod = true;
if (code0 == INTEGER_TYPE)
doing_div_or_mod = true;
warn_for_div_by_zero (location, cop1); warn_for_div_by_zero (location, cop1);
} }
...@@ -4902,7 +4897,8 @@ cp_build_binary_op (location_t location, ...@@ -4902,7 +4897,8 @@ cp_build_binary_op (location_t location,
if (build_type == NULL_TREE) if (build_type == NULL_TREE)
build_type = result_type; build_type = result_type;
if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE)) if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE
| SANITIZE_FLOAT_DIVIDE))
&& !processing_template_decl && !processing_template_decl
&& current_function_decl != 0 && current_function_decl != 0
&& !lookup_attribute ("no_sanitize_undefined", && !lookup_attribute ("no_sanitize_undefined",
...@@ -4916,7 +4912,8 @@ cp_build_binary_op (location_t location, ...@@ -4916,7 +4912,8 @@ cp_build_binary_op (location_t location,
tf_none)); tf_none));
op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1, op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1,
tf_none)); 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 /* For diagnostics we want to use the promoted types without
shorten_binary_op. So convert the arguments to the shorten_binary_op. So convert the arguments to the
......
...@@ -228,6 +228,7 @@ enum sanitize_code { ...@@ -228,6 +228,7 @@ enum sanitize_code {
SANITIZE_SI_OVERFLOW = 1 << 9, SANITIZE_SI_OVERFLOW = 1 << 9,
SANITIZE_BOOL = 1 << 10, SANITIZE_BOOL = 1 << 10,
SANITIZE_ENUM = 1 << 11, SANITIZE_ENUM = 1 << 11,
SANITIZE_FLOAT_DIVIDE = 1 << 12,
SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
| SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
| SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM
......
...@@ -8170,7 +8170,7 @@ sanitize_spec_function (int argc, const char **argv) ...@@ -8170,7 +8170,7 @@ sanitize_spec_function (int argc, const char **argv)
if (strcmp (argv[0], "thread") == 0) if (strcmp (argv[0], "thread") == 0)
return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL; return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
if (strcmp (argv[0], "undefined") == 0) 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; && !flag_sanitize_undefined_trap_on_error) ? "" : NULL;
if (strcmp (argv[0], "leak") == 0) if (strcmp (argv[0], "leak") == 0)
return ((flag_sanitize return ((flag_sanitize
......
...@@ -1461,6 +1461,8 @@ common_handle_option (struct gcc_options *opts, ...@@ -1461,6 +1461,8 @@ common_handle_option (struct gcc_options *opts,
sizeof "signed-integer-overflow" -1 }, sizeof "signed-integer-overflow" -1 },
{ "bool", SANITIZE_BOOL, sizeof "bool" - 1 }, { "bool", SANITIZE_BOOL, sizeof "bool" - 1 },
{ "enum", SANITIZE_ENUM, sizeof "enum" - 1 }, { "enum", SANITIZE_ENUM, sizeof "enum" - 1 },
{ "float-divide-by-zero", SANITIZE_FLOAT_DIVIDE,
sizeof "float-divide-by-zero" - 1 },
{ NULL, 0, 0 } { NULL, 0, 0 }
}; };
const char *comma; const char *comma;
......
2014-04-30 Marek Polacek <polacek@redhat.com> 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 PR c/60139
* gcc.dg/pr60139.c: New test. * gcc.dg/pr60139.c: New test.
......
/* { dg-do compile} */ /* { dg-do compile } */
/* { dg-options "-fsanitize=integer-divide-by-zero" } */ /* { dg-options "-fsanitize=integer-divide-by-zero" } */
void void
......
/* { 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]*" } */
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