From 9f8fafe847daf2c1bc1721d6d97203686567549d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 19 Jun 2017 17:28:42 +0200 Subject: [PATCH] re PR sanitizer/81125 (-fsanitize=undefined ICE) PR sanitizer/81125 * ubsan.h (enum ubsan_encode_value_phase): New. (ubsan_encode_value): Change second argument to enum ubsan_encode_value_phase with default value of UBSAN_ENCODE_VALUE_GENERIC. * ubsan.c (ubsan_encode_value): Change second argument to enum ubsan_encode_value_phase PHASE from bool IN_EXPAND_P, adjust uses, for UBSAN_ENCODE_VALUE_GENERIC use just create_tmp_var_raw instead of create_tmp_var and use a TARGET_EXPR. (ubsan_expand_bounds_ifn, ubsan_build_overflow_builtin, instrument_bool_enum_load, ubsan_instrument_float_cast): Adjust ubsan_encode_value callers. * g++.dg/ubsan/pr81125.C: New test. From-SVN: r249376 --- gcc/ChangeLog | 14 ++++++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/ubsan/pr81125.C | 20 +++++++++++++++++ gcc/ubsan.c | 32 +++++++++++++++------------- gcc/ubsan.h | 10 ++++++++- 5 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/pr81125.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c165b7f517f..396f112816b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,19 @@ 2017-06-19 Jakub Jelinek + PR sanitizer/81125 + * ubsan.h (enum ubsan_encode_value_phase): New. + (ubsan_encode_value): Change second argument to + enum ubsan_encode_value_phase with default value of + UBSAN_ENCODE_VALUE_GENERIC. + * ubsan.c (ubsan_encode_value): Change second argument to + enum ubsan_encode_value_phase PHASE from bool IN_EXPAND_P, + adjust uses, for UBSAN_ENCODE_VALUE_GENERIC use just + create_tmp_var_raw instead of create_tmp_var and use a + TARGET_EXPR. + (ubsan_expand_bounds_ifn, ubsan_build_overflow_builtin, + instrument_bool_enum_load, ubsan_instrument_float_cast): Adjust + ubsan_encode_value callers. + PR sanitizer/81111 * ubsan.c (ubsan_encode_value): If current_function_decl is NULL, use create_tmp_var_raw instead of create_tmp_var, mark it addressable diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b38e45edb8a..ecec6087d26 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-06-19 Jakub Jelinek + PR sanitizer/81125 + * g++.dg/ubsan/pr81125.C: New test. + PR sanitizer/81111 * g++.dg/ubsan/pr81111.C: New test. diff --git a/gcc/testsuite/g++.dg/ubsan/pr81125.C b/gcc/testsuite/g++.dg/ubsan/pr81125.C new file mode 100644 index 00000000000..c91ddc7db0e --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr81125.C @@ -0,0 +1,20 @@ +// PR sanitizer/81125 +// { dg-do compile } +// { dg-options "-fsanitize=undefined" } + +#ifdef __SIZEOF_INT128__ +typedef __int128 T; +#else +typedef long long int T; +#endif + +struct A +{ + A (long); + T a; +}; + +A::A (long c) +{ + long b = a % c; +} diff --git a/gcc/ubsan.c b/gcc/ubsan.c index 855b2ea0e79..44effdd2216 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -114,10 +114,10 @@ decl_for_type_insert (tree type, tree decl) /* Helper routine, which encodes a value in the pointer_sized_int_node. Arguments with precision <= POINTER_SIZE are passed directly, the rest is passed by reference. T is a value we are to encode. - IN_EXPAND_P is true if this function is called during expansion. */ + PHASE determines when this function is called. */ tree -ubsan_encode_value (tree t, bool in_expand_p) +ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase) { tree type = TREE_TYPE (t); const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type)); @@ -144,7 +144,7 @@ ubsan_encode_value (tree t, bool in_expand_p) /* The reason for this is that we don't want to pessimize code by making vars unnecessarily addressable. */ tree var; - if (current_function_decl) + if (phase != UBSAN_ENCODE_VALUE_GENERIC) { var = create_tmp_var (type); mark_addressable (var); @@ -154,7 +154,7 @@ ubsan_encode_value (tree t, bool in_expand_p) var = create_tmp_var_raw (type); TREE_ADDRESSABLE (var) = 1; } - if (in_expand_p) + if (phase == UBSAN_ENCODE_VALUE_RTL) { rtx mem = assign_stack_temp_for_type (TYPE_MODE (type), @@ -164,7 +164,7 @@ ubsan_encode_value (tree t, bool in_expand_p) expand_assignment (var, t, false); return build_fold_addr_expr (var); } - if (current_function_decl) + if (phase != UBSAN_ENCODE_VALUE_GENERIC) { tree tem = build2 (MODIFY_EXPR, void_type_node, var, t); t = build_fold_addr_expr (var); @@ -725,9 +725,9 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi) ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT; tree fn = builtin_decl_explicit (bcode); - tree val - = force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true, - NULL_TREE, true, GSI_SAME_STMT); + tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE); + val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true, + GSI_SAME_STMT); g = gimple_build_call (fn, 2, data, val); } gimple_set_location (g, loc); @@ -1283,9 +1283,11 @@ ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype, tree fn = builtin_decl_explicit (fn_code); return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR), build_fold_addr_expr_loc (loc, data), - ubsan_encode_value (op0, true), - op1 ? ubsan_encode_value (op1, true) - : NULL_TREE); + ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL), + op1 + ? ubsan_encode_value (op1, + UBSAN_ENCODE_VALUE_RTL) + : NULL_TREE); } /* Perform the signed integer instrumentation. GSI is the iterator @@ -1476,9 +1478,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi) : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT; tree fn = builtin_decl_explicit (bcode); - tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs), - true, NULL_TREE, true, - GSI_SAME_STMT); + tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE); + val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true, + GSI_SAME_STMT); g = gimple_build_call (fn, 2, data, val); } gimple_set_location (g, loc); @@ -1642,7 +1644,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr) fn = builtin_decl_explicit (bcode); fn = build_call_expr_loc (loc, fn, 2, build_fold_addr_expr_loc (loc, data), - ubsan_encode_value (expr, false)); + ubsan_encode_value (expr)); } return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node); diff --git a/gcc/ubsan.h b/gcc/ubsan.h index fddd359ebc3..6593423e93a 100644 --- a/gcc/ubsan.h +++ b/gcc/ubsan.h @@ -42,6 +42,13 @@ enum ubsan_print_style { UBSAN_PRINT_ARRAY }; +/* This controls ubsan_encode_value behavior. */ +enum ubsan_encode_value_phase { + UBSAN_ENCODE_VALUE_GENERIC, + UBSAN_ENCODE_VALUE_GIMPLE, + UBSAN_ENCODE_VALUE_RTL +}; + extern bool ubsan_expand_bounds_ifn (gimple_stmt_iterator *); extern bool ubsan_expand_null_ifn (gimple_stmt_iterator *); extern bool ubsan_expand_objsize_ifn (gimple_stmt_iterator *); @@ -49,7 +56,8 @@ extern bool ubsan_expand_vptr_ifn (gimple_stmt_iterator *); extern bool ubsan_instrument_unreachable (gimple_stmt_iterator *); extern tree ubsan_create_data (const char *, int, const location_t *, ...); extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NORMAL); -extern tree ubsan_encode_value (tree, bool = false); +extern tree ubsan_encode_value (tree, enum ubsan_encode_value_phase + = UBSAN_ENCODE_VALUE_GENERIC); extern bool is_ubsan_builtin_p (tree); extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree, tree *); -- 2.30.2