This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix yet another -fsanitize=undefined ubsan_encode_value ICE (PR sanitizer/81125)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Martin Liška <mliska at suse dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 Jun 2017 16:44:17 +0200
- Subject: [PATCH] Fix yet another -fsanitize=undefined ubsan_encode_value ICE (PR sanitizer/81125)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3D8AFC04BD30
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3D8AFC04BD30
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
And here is another ICE. While we have a current_function_decl
in this case, still create_tmp_var's called gimple_add_tmp_var
and mark_addressable don't work too well when the current function
is a C++ ctor or dtor that the FE then duplicates.
Fixed by telling ubsan_encode_value whether it is called from the
FE (when it shouldn't use gimple_add_tmp_var nor mark_addressable
and should use TARGET_EXPR), or from GIMPLE passes (when it should
do what it did before with in_expand_p == false) or from RTL expansion
(when it should do what it did with in_expand_p == true).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-06-19 Jakub Jelinek <jakub@redhat.com>
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.
--- gcc/ubsan.h.jj 2017-06-19 08:26:17.000000000 +0200
+++ gcc/ubsan.h 2017-06-19 10:06:52.723664974 +0200
@@ -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 (gimpl
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 *);
--- gcc/ubsan.c.jj 2017-06-19 10:27:33.000000000 +0200
+++ gcc/ubsan.c 2017-06-19 10:13:53.434541556 +0200
@@ -114,10 +114,10 @@ decl_for_type_insert (tree type, tree de
/* 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_expa
/* 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_expa
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_expa
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_ite
? 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
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_i
: 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
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);
--- gcc/testsuite/g++.dg/ubsan/pr81125.C.jj 2017-06-19 10:21:58.607642573 +0200
+++ gcc/testsuite/g++.dg/ubsan/pr81125.C 2017-06-19 10:21:28.000000000 +0200
@@ -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;
+}
Jakub