aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2013-12-05 18:03:44 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2013-12-05 18:03:44 +0000
commit1769415d4a5b8da1a07ad91bb073c5ae50cebabd (patch)
treed6c513523dadd6906703a923781d3f66bc4ebeee /gcc
parent8fde427f4fa132c7d86197c6273c1ef4729f3ae5 (diff)
downloadgcc-1769415d4a5b8da1a07ad91bb073c5ae50cebabd.zip
gcc-1769415d4a5b8da1a07ad91bb073c5ae50cebabd.tar.gz
gcc-1769415d4a5b8da1a07ad91bb073c5ae50cebabd.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/internal-fn.c30
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr59333.c19
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr59397.c10
-rw-r--r--gcc/ubsan.c80
-rw-r--r--gcc/ubsan.h2
7 files changed, 117 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 58f9782..55757a0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2013-12-05 Marek Polacek <polacek@redhat.com>
+
+ 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 <yufeng.zhang@arm.com>
* gimple-ssa-strength-reduction.c (find_basis_for_candidate): Guard
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 527b5ff..fb1e578 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 d9f7de3..62010b2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2013-12-05 Marek Polacek <polacek@redhat.com>
+
+ 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 <tejas.belagod@arm.com>
* 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 0000000..af53920
--- /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 0000000..0de0258
--- /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 aaf74ac..846e884 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 0aced4a..fa76985 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);