From: Marek Polacek Date: Thu, 5 Dec 2013 18:03:44 +0000 (+0000) Subject: re PR sanitizer/59333 (ICE with long long and -m32 -fsanitize=undefined) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1769415d4a5b8da1a07ad91bb073c5ae50cebabd;p=gcc.git re PR sanitizer/59333 (ICE with long long and -m32 -fsanitize=undefined) PR sanitizer/59333 PR sanitizer/59397 * ubsan.c: Include rtl.h and expr.h. (ubsan_encode_value): Add new parameter. If expanding, assign a stack slot for DECL_RTL of the temporary and call expand_assignment. Handle BOOLEAN_TYPE and ENUMERAL_TYPE. (ubsan_build_overflow_builtin): Adjust ubsan_encode_value call. * ubsan.h (ubsan_encode_value): Adjust declaration. * internal-fn.c (ubsan_expand_si_overflow_addsub_check): Move ubsan_build_overflow_builtin above expand_normal call. Surround this call with push_temp_slots and pop_temp_slots. (ubsan_expand_si_overflow_neg_check): Likewise. (ubsan_expand_si_overflow_mul_check): Likewise. testsuite/ * c-c++-common/ubsan/pr59333.c: New test. * c-c++-common/ubsan/pr59397.c: New test. From-SVN: r205714 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 58f9782598b..55757a06caf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-12-05 Marek Polacek + + PR sanitizer/59333 + PR sanitizer/59397 + * ubsan.c: Include rtl.h and expr.h. + (ubsan_encode_value): Add new parameter. If expanding, assign + a stack slot for DECL_RTL of the temporary and call expand_assignment. + Handle BOOLEAN_TYPE and ENUMERAL_TYPE. + (ubsan_build_overflow_builtin): Adjust ubsan_encode_value call. + * ubsan.h (ubsan_encode_value): Adjust declaration. + * internal-fn.c (ubsan_expand_si_overflow_addsub_check): Move + ubsan_build_overflow_builtin above expand_normal call. Surround this call + with push_temp_slots and pop_temp_slots. + (ubsan_expand_si_overflow_neg_check): Likewise. + (ubsan_expand_si_overflow_mul_check): Likewise. + 2013-12-05 Yufeng Zhang * gimple-ssa-strength-reduction.c (find_basis_for_candidate): Guard diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 527b5ffaf7f..fb1e5784b15 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -171,8 +171,6 @@ ubsan_expand_si_overflow_addsub_check (tree_code code, gimple stmt) arg1 = gimple_call_arg (stmt, 1); done_label = gen_label_rtx (); do_error = gen_label_rtx (); - fn = ubsan_build_overflow_builtin (code, gimple_location (stmt), - TREE_TYPE (arg0), arg0, arg1); do_pending_stack_adjust (); op0 = expand_normal (arg0); op1 = expand_normal (arg1); @@ -237,13 +235,17 @@ ubsan_expand_si_overflow_addsub_check (tree_code code, gimple stmt) PROB_VERY_LIKELY); } - emit_label (do_error); - /* Expand the ubsan builtin call. */ - expand_normal (fn); - do_pending_stack_adjust (); + emit_label (do_error); + /* Expand the ubsan builtin call. */ + push_temp_slots (); + fn = ubsan_build_overflow_builtin (code, gimple_location (stmt), + TREE_TYPE (arg0), arg0, arg1); + expand_normal (fn); + pop_temp_slots (); + do_pending_stack_adjust (); - /* We're done. */ - emit_label (done_label); + /* We're done. */ + emit_label (done_label); if (lhs) emit_move_insn (target, res); @@ -262,8 +264,6 @@ ubsan_expand_si_overflow_neg_check (gimple stmt) arg1 = gimple_call_arg (stmt, 1); done_label = gen_label_rtx (); do_error = gen_label_rtx (); - fn = ubsan_build_overflow_builtin (NEGATE_EXPR, gimple_location (stmt), - TREE_TYPE (arg1), arg1, NULL_TREE); do_pending_stack_adjust (); op1 = expand_normal (arg1); @@ -313,7 +313,11 @@ ubsan_expand_si_overflow_neg_check (gimple stmt) emit_label (do_error); /* Expand the ubsan builtin call. */ + push_temp_slots (); + fn = ubsan_build_overflow_builtin (NEGATE_EXPR, gimple_location (stmt), + TREE_TYPE (arg1), arg1, NULL_TREE); expand_normal (fn); + pop_temp_slots (); do_pending_stack_adjust (); /* We're done. */ @@ -337,8 +341,6 @@ ubsan_expand_si_overflow_mul_check (gimple stmt) arg1 = gimple_call_arg (stmt, 1); done_label = gen_label_rtx (); do_error = gen_label_rtx (); - fn = ubsan_build_overflow_builtin (MULT_EXPR, gimple_location (stmt), - TREE_TYPE (arg0), arg0, arg1); do_pending_stack_adjust (); op0 = expand_normal (arg0); @@ -418,7 +420,11 @@ ubsan_expand_si_overflow_mul_check (gimple stmt) emit_label (do_error); /* Expand the ubsan builtin call. */ + push_temp_slots (); + fn = ubsan_build_overflow_builtin (MULT_EXPR, gimple_location (stmt), + TREE_TYPE (arg0), arg0, arg1); expand_normal (fn); + pop_temp_slots (); do_pending_stack_adjust (); /* We're done. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d9f7de3a38d..62010b269a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-12-05 Marek Polacek + + PR sanitizer/59333 + PR sanitizer/59397 + * c-c++-common/ubsan/pr59333.c: New test. + * c-c++-common/ubsan/pr59397.c: New test. + 2013-12-05 Tejas Belagod * gcc.dg/vect/vect-nop-move.c: New test. diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59333.c b/gcc/testsuite/c-c++-common/ubsan/pr59333.c new file mode 100644 index 00000000000..af539204960 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr59333.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=undefined" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ + +long long int __attribute__ ((noinline, noclone)) +foo (long long int i, long long int j) +{ + asm (""); + return i + j; +} + +int +main (void) +{ + foo (2LL, __LONG_LONG_MAX__); + return 0; +} + +/* { dg-output "signed integer overflow: 2 \\+ 9223372036854775807 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59397.c b/gcc/testsuite/c-c++-common/ubsan/pr59397.c new file mode 100644 index 00000000000..0de02583519 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr59397.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=signed-integer-overflow" } */ + +typedef enum E { A = -1 } e; +int +foo (void) +{ + e e = A; + return e + 1; +} diff --git a/gcc/ubsan.c b/gcc/ubsan.c index aaf74acb546..846e884de52 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "tree-pass.h" #include "tree-ssa-alias.h" +#include "tree-pretty-print.h" #include "internal-fn.h" #include "gimple-expr.h" #include "gimple.h" @@ -40,6 +41,8 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "ubsan.h" #include "c-family/c-common.h" +#include "rtl.h" +#include "expr.h" /* Map from a tree to a VAR_DECL tree. */ @@ -102,45 +105,53 @@ 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. */ + 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. */ tree -ubsan_encode_value (tree t) +ubsan_encode_value (tree t, bool in_expand_p) { tree type = TREE_TYPE (t); - switch (TREE_CODE (type)) - { - case INTEGER_TYPE: - if (TYPE_PRECISION (type) <= POINTER_SIZE) + const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type)); + if (bitsize <= POINTER_SIZE) + switch (TREE_CODE (type)) + { + case BOOLEAN_TYPE: + case ENUMERAL_TYPE: + case INTEGER_TYPE: return fold_build1 (NOP_EXPR, pointer_sized_int_node, t); + case REAL_TYPE: + { + tree itype = build_nonstandard_integer_type (bitsize, true); + t = fold_build1 (VIEW_CONVERT_EXPR, itype, t); + return fold_convert (pointer_sized_int_node, t); + } + default: + gcc_unreachable (); + } + else + { + if (!DECL_P (t) || !TREE_ADDRESSABLE (t)) + { + /* The reason for this is that we don't want to pessimize + code by making vars unnecessarily addressable. */ + tree var = create_tmp_var (type, NULL); + tree tem = build2 (MODIFY_EXPR, void_type_node, var, t); + if (in_expand_p) + { + rtx mem + = assign_stack_temp_for_type (TYPE_MODE (type), + GET_MODE_SIZE (TYPE_MODE (type)), + type); + SET_DECL_RTL (var, mem); + expand_assignment (var, t, false); + return build_fold_addr_expr (var); + } + t = build_fold_addr_expr (var); + return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t); + } else return build_fold_addr_expr (t); - case REAL_TYPE: - { - unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type)); - if (bitsize <= POINTER_SIZE) - { - tree itype = build_nonstandard_integer_type (bitsize, true); - t = fold_build1 (VIEW_CONVERT_EXPR, itype, t); - return fold_convert (pointer_sized_int_node, t); - } - else - { - if (!TREE_ADDRESSABLE (t)) - { - /* The reason for this is that we don't want to pessimize - code by making vars unnecessarily addressable. */ - tree var = create_tmp_var (TREE_TYPE (t), NULL); - tree tem = build2 (MODIFY_EXPR, void_type_node, var, t); - t = build_fold_addr_expr (var); - return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t); - } - else - return build_fold_addr_expr (t); - } - } - default: - gcc_unreachable (); } } @@ -663,8 +674,9 @@ 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), - op1 ? ubsan_encode_value (op1) : NULL_TREE); + ubsan_encode_value (op0, true), + op1 ? ubsan_encode_value (op1, true) + : NULL_TREE); } /* Perform the signed integer instrumentation. GSI is the iterator diff --git a/gcc/ubsan.h b/gcc/ubsan.h index 0aced4aac67..fa7698509c4 100644 --- a/gcc/ubsan.h +++ b/gcc/ubsan.h @@ -41,7 +41,7 @@ extern tree ubsan_instrument_unreachable (location_t); extern tree ubsan_create_data (const char *, location_t, const struct ubsan_mismatch_data *, ...); extern tree ubsan_type_descriptor (tree, bool); -extern tree ubsan_encode_value (tree); +extern tree ubsan_encode_value (tree, bool = false); extern bool is_ubsan_builtin_p (tree); extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree);