Commit 9f8fafe8 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 4301ae22
2017-06-19 Jakub Jelinek <jakub@redhat.com> 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.
PR sanitizer/81111 PR sanitizer/81111
* ubsan.c (ubsan_encode_value): If current_function_decl is NULL, * ubsan.c (ubsan_encode_value): If current_function_decl is NULL,
use create_tmp_var_raw instead of create_tmp_var, mark it addressable use create_tmp_var_raw instead of create_tmp_var, mark it addressable
......
2017-06-19 Jakub Jelinek <jakub@redhat.com> 2017-06-19 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/81125
* g++.dg/ubsan/pr81125.C: New test.
PR sanitizer/81111 PR sanitizer/81111
* g++.dg/ubsan/pr81111.C: New test. * g++.dg/ubsan/pr81111.C: New test.
......
// 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;
}
...@@ -114,10 +114,10 @@ decl_for_type_insert (tree type, tree decl) ...@@ -114,10 +114,10 @@ decl_for_type_insert (tree type, tree decl)
/* Helper routine, which encodes a value in the pointer_sized_int_node. /* Helper routine, which encodes a value in the pointer_sized_int_node.
Arguments with precision <= POINTER_SIZE are passed directly, 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. */ PHASE determines when this function is called. */
tree 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); tree type = TREE_TYPE (t);
const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type)); const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
...@@ -144,7 +144,7 @@ ubsan_encode_value (tree t, bool in_expand_p) ...@@ -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 /* The reason for this is that we don't want to pessimize
code by making vars unnecessarily addressable. */ code by making vars unnecessarily addressable. */
tree var; tree var;
if (current_function_decl) if (phase != UBSAN_ENCODE_VALUE_GENERIC)
{ {
var = create_tmp_var (type); var = create_tmp_var (type);
mark_addressable (var); mark_addressable (var);
...@@ -154,7 +154,7 @@ ubsan_encode_value (tree t, bool in_expand_p) ...@@ -154,7 +154,7 @@ ubsan_encode_value (tree t, bool in_expand_p)
var = create_tmp_var_raw (type); var = create_tmp_var_raw (type);
TREE_ADDRESSABLE (var) = 1; TREE_ADDRESSABLE (var) = 1;
} }
if (in_expand_p) if (phase == UBSAN_ENCODE_VALUE_RTL)
{ {
rtx mem rtx mem
= assign_stack_temp_for_type (TYPE_MODE (type), = assign_stack_temp_for_type (TYPE_MODE (type),
...@@ -164,7 +164,7 @@ ubsan_encode_value (tree t, bool in_expand_p) ...@@ -164,7 +164,7 @@ ubsan_encode_value (tree t, bool in_expand_p)
expand_assignment (var, t, false); expand_assignment (var, t, false);
return build_fold_addr_expr (var); 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); tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
t = build_fold_addr_expr (var); t = build_fold_addr_expr (var);
...@@ -725,9 +725,9 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi) ...@@ -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
: BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT; : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
tree fn = builtin_decl_explicit (bcode); tree fn = builtin_decl_explicit (bcode);
tree val tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
= force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true, val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
NULL_TREE, true, GSI_SAME_STMT); GSI_SAME_STMT);
g = gimple_build_call (fn, 2, data, val); g = gimple_build_call (fn, 2, data, val);
} }
gimple_set_location (g, loc); gimple_set_location (g, loc);
...@@ -1283,9 +1283,11 @@ ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype, ...@@ -1283,9 +1283,11 @@ ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
tree fn = builtin_decl_explicit (fn_code); tree fn = builtin_decl_explicit (fn_code);
return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR), return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
build_fold_addr_expr_loc (loc, data), build_fold_addr_expr_loc (loc, data),
ubsan_encode_value (op0, true), ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
op1 ? ubsan_encode_value (op1, true) op1
: NULL_TREE); ? ubsan_encode_value (op1,
UBSAN_ENCODE_VALUE_RTL)
: NULL_TREE);
} }
/* Perform the signed integer instrumentation. GSI is the iterator /* Perform the signed integer instrumentation. GSI is the iterator
...@@ -1476,9 +1478,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi) ...@@ -1476,9 +1478,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
: BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT; : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
tree fn = builtin_decl_explicit (bcode); tree fn = builtin_decl_explicit (bcode);
tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs), tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
true, NULL_TREE, true, val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
GSI_SAME_STMT); GSI_SAME_STMT);
g = gimple_build_call (fn, 2, data, val); g = gimple_build_call (fn, 2, data, val);
} }
gimple_set_location (g, loc); gimple_set_location (g, loc);
...@@ -1642,7 +1644,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr) ...@@ -1642,7 +1644,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
fn = builtin_decl_explicit (bcode); fn = builtin_decl_explicit (bcode);
fn = build_call_expr_loc (loc, fn, 2, fn = build_call_expr_loc (loc, fn, 2,
build_fold_addr_expr_loc (loc, data), 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); return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
......
...@@ -42,6 +42,13 @@ enum ubsan_print_style { ...@@ -42,6 +42,13 @@ enum ubsan_print_style {
UBSAN_PRINT_ARRAY 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_bounds_ifn (gimple_stmt_iterator *);
extern bool ubsan_expand_null_ifn (gimple_stmt_iterator *); extern bool ubsan_expand_null_ifn (gimple_stmt_iterator *);
extern bool ubsan_expand_objsize_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 *); ...@@ -49,7 +56,8 @@ extern bool ubsan_expand_vptr_ifn (gimple_stmt_iterator *);
extern bool ubsan_instrument_unreachable (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_create_data (const char *, int, const location_t *, ...);
extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NORMAL); 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 bool is_ubsan_builtin_p (tree);
extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree,
tree, tree *); tree, tree *);
......
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