本文整理汇总了C++中build_int_cst函数的典型用法代码示例。如果您正苦于以下问题:C++ build_int_cst函数的具体用法?C++ build_int_cst怎么用?C++ build_int_cst使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了build_int_cst函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: gen_one_condition
static void
gen_one_condition (tree arg, int lbub,
enum tree_code tcode,
const char *temp_name1,
const char *temp_name2,
vec<gimple *> conds,
unsigned *nconds)
{
tree lbub_real_cst, lbub_cst, float_type;
tree temp, tempn, tempc, tempcn;
gassign *stmt1;
gassign *stmt2;
gcond *stmt3;
float_type = TREE_TYPE (arg);
lbub_cst = build_int_cst (integer_type_node, lbub);
lbub_real_cst = build_real_from_int_cst (float_type, lbub_cst);
temp = create_tmp_var (float_type, temp_name1);
stmt1 = gimple_build_assign (temp, arg);
tempn = make_ssa_name (temp, stmt1);
gimple_assign_set_lhs (stmt1, tempn);
tempc = create_tmp_var (boolean_type_node, temp_name2);
stmt2 = gimple_build_assign (tempc,
fold_build2 (tcode,
boolean_type_node,
tempn, lbub_real_cst));
tempcn = make_ssa_name (tempc, stmt2);
gimple_assign_set_lhs (stmt2, tempcn);
stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE);
conds.quick_push (stmt1);
conds.quick_push (stmt2);
conds.quick_push (stmt3);
(*nconds)++;
}
示例2: build_ivar_list_initializer
tree
build_ivar_list_initializer (tree type, tree field_decl)
{
vec<constructor_elt, va_gc> *inits = NULL;
do
{
vec<constructor_elt, va_gc> *ivar = NULL;
tree id;
/* Set name. */
if (DECL_NAME (field_decl))
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
add_objc_string (DECL_NAME (field_decl),
meth_var_names));
else
/* Unnamed bit-field ivar (yuck). */
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
/* Set type. */
id = add_objc_string (encode_field_decl (field_decl),
meth_var_types);
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
/* Set offset. */
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
objc_build_constructor (type, ivar));
do
field_decl = DECL_CHAIN (field_decl);
while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
}
while (field_decl);
return objc_build_constructor (build_array_type (type, 0), inits);
}
示例3: vxworks_emutls_var_init
static tree
vxworks_emutls_var_init (tree var, tree decl, tree tmpl_addr)
{
vec<constructor_elt, va_gc> *v;
vec_alloc (v, 3);
tree type = TREE_TYPE (var);
tree field = TYPE_FIELDS (type);
constructor_elt elt = {field, fold_convert (TREE_TYPE (field), tmpl_addr)};
v->quick_push (elt);
field = DECL_CHAIN (field);
elt.index = field;
elt.value = build_int_cst (TREE_TYPE (field), 0);
v->quick_push (elt);
field = DECL_CHAIN (field);
elt.index = field;
elt.value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl));
v->quick_push (elt);
return build_constructor (type, v);
}
示例4: gfc_conv_constant_to_tree
tree
gfc_conv_constant_to_tree (gfc_expr * expr)
{
gcc_assert (expr->expr_type == EXPR_CONSTANT);
switch (expr->ts.type)
{
case BT_INTEGER:
return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
case BT_REAL:
return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind);
case BT_LOGICAL:
return build_int_cst (gfc_get_logical_type (expr->ts.kind),
expr->value.logical);
case BT_COMPLEX:
{
tree real = gfc_conv_mpfr_to_tree (expr->value.complex.r,
expr->ts.kind);
tree imag = gfc_conv_mpfr_to_tree (expr->value.complex.i,
expr->ts.kind);
return build_complex (NULL_TREE, real, imag);
}
case BT_CHARACTER:
return gfc_build_string_const (expr->value.character.length,
expr->value.character.string);
default:
fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
gfc_typename (&expr->ts));
}
}
示例5: insert_add_fn
/* Insert a call to the runtime function "__slimer_add_fn" which will add the
* "junk" function created at compile-time to an array at runtime
*/
static void insert_add_fn(gimple stmt, int index)
{
tree fn;
gimple call;
gimple_stmt_iterator gsi;
static tree decl, proto, idx;
if (!decl || !proto)
{
proto = build_function_type_list(void_type_node, ptr_type_node,
integer_type_node, NULL_TREE);
decl = build_fn_decl("__slimer_add_fn", proto);
/* Add this fndecl to our list of things we do not process */
VEC_safe_push(tree, gc, analyized_fns, decl);
}
/* Create a constant value and pointer to the function we are to add */
idx = build_int_cst(integer_type_node, index);
fn = build_addr(VEC_index(tree, fakes, index), NULL_TREE);
call = gimple_build_call(decl, 2, fn, idx);
gsi = gsi_for_stmt(stmt);
gsi_insert_before(&gsi, call, GSI_NEW_STMT);
}
示例6: ifcombine_iforif
static bool
ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
{
gimple inner_cond, outer_cond;
tree name1, name2, bits1, bits2;
inner_cond = last_stmt (inner_cond_bb);
if (!inner_cond
|| gimple_code (inner_cond) != GIMPLE_COND)
return false;
outer_cond = last_stmt (outer_cond_bb);
if (!outer_cond
|| gimple_code (outer_cond) != GIMPLE_COND)
return false;
/* See if we have two bit tests of the same name in both tests.
In that case remove the outer test and change the inner one to
test for name & (bits1 | bits2) != 0. */
if (recognize_bits_test (inner_cond, &name1, &bits1)
&& recognize_bits_test (outer_cond, &name2, &bits2))
{
gimple_stmt_iterator gsi;
tree t;
/* Find the common name which is bit-tested. */
if (name1 == name2)
;
else if (bits1 == bits2)
{
t = name2;
name2 = bits2;
bits2 = t;
t = name1;
name1 = bits1;
bits1 = t;
}
else if (name1 == bits2)
{
t = name2;
name2 = bits2;
bits2 = t;
}
else if (bits1 == name2)
{
t = name1;
name1 = bits1;
bits1 = t;
}
else
return false;
/* As we strip non-widening conversions in finding a common
name that is tested make sure to end up with an integral
type for building the bit operations. */
if (TYPE_PRECISION (TREE_TYPE (bits1))
>= TYPE_PRECISION (TREE_TYPE (bits2)))
{
bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
name1 = fold_convert (TREE_TYPE (bits1), name1);
bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
bits2 = fold_convert (TREE_TYPE (bits1), bits2);
}
else
{
bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
name1 = fold_convert (TREE_TYPE (bits2), name1);
bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
bits1 = fold_convert (TREE_TYPE (bits2), bits1);
}
/* Do it. */
gsi = gsi_for_stmt (inner_cond);
t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
true, GSI_SAME_STMT);
t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
true, GSI_SAME_STMT);
t = fold_build2 (NE_EXPR, boolean_type_node, t,
build_int_cst (TREE_TYPE (t), 0));
gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
update_stmt (outer_cond);
if (dump_file)
{
fprintf (dump_file, "optimizing bits or bits test to ");
print_generic_expr (dump_file, name1, 0);
fprintf (dump_file, " & T != 0\nwith temporary T = ");
print_generic_expr (dump_file, bits1, 0);
fprintf (dump_file, " | ");
print_generic_expr (dump_file, bits2, 0);
fprintf (dump_file, "\n");
}
return true;
//.........这里部分代码省略.........
示例7: aarch64_atomic_assign_expand_fenv
void
aarch64_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
{
const unsigned AARCH64_FE_INVALID = 1;
const unsigned AARCH64_FE_DIVBYZERO = 2;
const unsigned AARCH64_FE_OVERFLOW = 4;
const unsigned AARCH64_FE_UNDERFLOW = 8;
const unsigned AARCH64_FE_INEXACT = 16;
const unsigned HOST_WIDE_INT AARCH64_FE_ALL_EXCEPT = (AARCH64_FE_INVALID
| AARCH64_FE_DIVBYZERO
| AARCH64_FE_OVERFLOW
| AARCH64_FE_UNDERFLOW
| AARCH64_FE_INEXACT);
const unsigned HOST_WIDE_INT AARCH64_FE_EXCEPT_SHIFT = 8;
tree fenv_cr, fenv_sr, get_fpcr, set_fpcr, mask_cr, mask_sr;
tree ld_fenv_cr, ld_fenv_sr, masked_fenv_cr, masked_fenv_sr, hold_fnclex_cr;
tree hold_fnclex_sr, new_fenv_var, reload_fenv, restore_fnenv, get_fpsr, set_fpsr;
tree update_call, atomic_feraiseexcept, hold_fnclex, masked_fenv, ld_fenv;
/* Generate the equivalence of :
unsigned int fenv_cr;
fenv_cr = __builtin_aarch64_get_fpcr ();
unsigned int fenv_sr;
fenv_sr = __builtin_aarch64_get_fpsr ();
Now set all exceptions to non-stop
unsigned int mask_cr
= ~(AARCH64_FE_ALL_EXCEPT << AARCH64_FE_EXCEPT_SHIFT);
unsigned int masked_cr;
masked_cr = fenv_cr & mask_cr;
And clear all exception flags
unsigned int maske_sr = ~AARCH64_FE_ALL_EXCEPT;
unsigned int masked_cr;
masked_sr = fenv_sr & mask_sr;
__builtin_aarch64_set_cr (masked_cr);
__builtin_aarch64_set_sr (masked_sr); */
fenv_cr = create_tmp_var (unsigned_type_node, NULL);
fenv_sr = create_tmp_var (unsigned_type_node, NULL);
get_fpcr = aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR];
set_fpcr = aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR];
get_fpsr = aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR];
set_fpsr = aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR];
mask_cr = build_int_cst (unsigned_type_node,
~(AARCH64_FE_ALL_EXCEPT << AARCH64_FE_EXCEPT_SHIFT));
mask_sr = build_int_cst (unsigned_type_node,
~(AARCH64_FE_ALL_EXCEPT));
ld_fenv_cr = build2 (MODIFY_EXPR, unsigned_type_node,
fenv_cr, build_call_expr (get_fpcr, 0));
ld_fenv_sr = build2 (MODIFY_EXPR, unsigned_type_node,
fenv_sr, build_call_expr (get_fpsr, 0));
masked_fenv_cr = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_cr, mask_cr);
masked_fenv_sr = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_sr, mask_sr);
hold_fnclex_cr = build_call_expr (set_fpcr, 1, masked_fenv_cr);
hold_fnclex_sr = build_call_expr (set_fpsr, 1, masked_fenv_sr);
hold_fnclex = build2 (COMPOUND_EXPR, void_type_node, hold_fnclex_cr,
hold_fnclex_sr);
masked_fenv = build2 (COMPOUND_EXPR, void_type_node, masked_fenv_cr,
masked_fenv_sr);
ld_fenv = build2 (COMPOUND_EXPR, void_type_node, ld_fenv_cr, ld_fenv_sr);
*hold = build2 (COMPOUND_EXPR, void_type_node,
build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
hold_fnclex);
/* Store the value of masked_fenv to clear the exceptions:
__builtin_aarch64_set_fpsr (masked_fenv_sr); */
*clear = build_call_expr (set_fpsr, 1, masked_fenv_sr);
/* Generate the equivalent of :
unsigned int new_fenv_var;
new_fenv_var = __builtin_aarch64_get_fpsr ();
__builtin_aarch64_set_fpsr (fenv_sr);
__atomic_feraiseexcept (new_fenv_var); */
new_fenv_var = create_tmp_var (unsigned_type_node, NULL);
reload_fenv = build2 (MODIFY_EXPR, unsigned_type_node,
new_fenv_var, build_call_expr (get_fpsr, 0));
restore_fnenv = build_call_expr (set_fpsr, 1, fenv_sr);
atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
update_call = build_call_expr (atomic_feraiseexcept, 1,
fold_convert (integer_type_node, new_fenv_var));
*update = build2 (COMPOUND_EXPR, void_type_node,
build2 (COMPOUND_EXPR, void_type_node,
reload_fenv, restore_fnenv), update_call);
}
示例8: my_dump_gimple
static void
my_dump_gimple(gimple gnode, gimple_stmt_iterator *ptrgsi)
{
int gcode;
tree tnode;
tree funcdecl;
tree desc_node;
tree ptr_desc_node;
tree t;
tree tmp_var;
tree const_char_restrict_ptr_type_node;
gimple tmp_gstmt;
gimple new_gnode;
const char *hellocstr = "Hello, GCC!\n";
int i;
struct c_binding *b;
expanded_location xloc;
/*
* Extract the Gimple Code from a gimple node
*/
gcode = gimple_code(gnode);
/*
* Get the line number of cooresponding
* source code from a gimple node
*/
if(gimple_has_location(gnode))
{
xloc = expand_location(gimple_location(gnode));
printf("line %d:", xloc.line);
}
printf("\t\t\t\t%s\n", gimple_code_name[gcode]);
switch(gcode)
{
case GIMPLE_ASSIGN:
/*
* Add a printf("Hello, GCC!\n"); statement
* after the first appearing assignment
* if yes equals to 1, then we have already
* added the statement, and no need to add
* again
*/
if(!yes)
{
/*
* Since printf is a builtin function, we need
* to get the function declaration using
* built_in_decls[]. The index number can be
* found in gcc source gcc/builtins.def
*/
funcdecl = built_in_decls[BUILT_IN_PRINTF];
if(funcdecl == NULL_TREE)
{
printf("cannot find printf\n");
}
else
{
/*
* In gimple, every statement is simplified into
* three oprands mode. And our printf() statement
* is change into following two gimple statements:
*
* <D.XXX> = (const char * restrict) &"Hello, GCC!\n"[0]
* printf(<D.XXX>);
*
* Note that <D.XXX> is a temporary variable, we can
* actually use any name we like as long as no
* confliction.
*/
/*
* Generate a STRING_CST, the value is "Hello, GCC!\n"
*/
desc_node = build_string(strlen(hellocstr), hellocstr);
/*
* Two points need to notice here:
* 1. STRING_CST build by build_string() do
* not have TREE_TYPE set, so we need to
* set it manually.
* 2. build_string() will add a trailing '\0'
* when building the STRING_CST, so we do
* not need to care with it.
*/
TREE_TYPE(desc_node) = build_array_type(
char_type_node,
build_index_type(
build_int_cst(NULL_TREE,
strlen(hellocstr))));
/*
* Define a const char * restrict type node
* here for convertion.
* I'm not sure why we need to add a restrict
* attribute, but GCC really does it when it
* converting a STRING_CST from AST to Gimple.
//.........这里部分代码省略.........
示例9: build_field
static void
build_field (segment_info *h, tree union_type, record_layout_info rli)
{
tree field;
tree name;
HOST_WIDE_INT offset = h->offset;
unsigned HOST_WIDE_INT desired_align, known_align;
name = get_identifier (h->sym->name);
field = build_decl (h->sym->declared_at.lb->location,
FIELD_DECL, name, h->field);
known_align = (offset & -offset) * BITS_PER_UNIT;
if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
known_align = BIGGEST_ALIGNMENT;
desired_align = update_alignment_for_field (rli, field, known_align);
if (desired_align > known_align)
DECL_PACKED (field) = 1;
DECL_FIELD_CONTEXT (field) = union_type;
DECL_FIELD_OFFSET (field) = size_int (offset);
DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
SET_DECL_OFFSET_ALIGN (field, known_align);
rli->offset = size_binop (MAX_EXPR, rli->offset,
size_binop (PLUS_EXPR,
DECL_FIELD_OFFSET (field),
DECL_SIZE_UNIT (field)));
/* If this field is assigned to a label, we create another two variables.
One will hold the address of target label or format label. The other will
hold the length of format label string. */
if (h->sym->attr.assign)
{
tree len;
tree addr;
gfc_allocate_lang_decl (field);
GFC_DECL_ASSIGN (field) = 1;
len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name);
addr = gfc_create_var_np (pvoid_type_node, h->sym->name);
TREE_STATIC (len) = 1;
TREE_STATIC (addr) = 1;
DECL_INITIAL (len) = build_int_cst (gfc_charlen_type_node, -2);
gfc_set_decl_location (len, &h->sym->declared_at);
gfc_set_decl_location (addr, &h->sym->declared_at);
GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len);
GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr);
}
/* If this field is volatile, mark it. */
if (h->sym->attr.volatile_)
{
tree new_type;
TREE_THIS_VOLATILE (field) = 1;
TREE_SIDE_EFFECTS (field) = 1;
new_type = build_qualified_type (TREE_TYPE (field), TYPE_QUAL_VOLATILE);
TREE_TYPE (field) = new_type;
}
h->field = field;
}
示例10: gfc_conv_constant_to_tree
tree
gfc_conv_constant_to_tree (gfc_expr * expr)
{
tree res;
gcc_assert (expr->expr_type == EXPR_CONSTANT);
/* If it is has a prescribed memory representation, we build a string
constant and VIEW_CONVERT to its type. */
switch (expr->ts.type)
{
case BT_INTEGER:
if (expr->representation.string)
return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
gfc_get_int_type (expr->ts.kind),
gfc_build_string_const (expr->representation.length,
expr->representation.string));
else
return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
case BT_REAL:
if (expr->representation.string)
return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
gfc_get_real_type (expr->ts.kind),
gfc_build_string_const (expr->representation.length,
expr->representation.string));
else
return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind, expr->is_snan);
case BT_LOGICAL:
if (expr->representation.string)
{
tree tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
gfc_get_int_type (expr->ts.kind),
gfc_build_string_const (expr->representation.length,
expr->representation.string));
if (!integer_zerop (tmp) && !integer_onep (tmp))
gfc_warning ("Assigning value other than 0 or 1 to LOGICAL"
" has undefined result at %L", &expr->where);
return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
}
else
return build_int_cst (gfc_get_logical_type (expr->ts.kind),
expr->value.logical);
case BT_COMPLEX:
if (expr->representation.string)
return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
gfc_get_complex_type (expr->ts.kind),
gfc_build_string_const (expr->representation.length,
expr->representation.string));
else
{
tree real = gfc_conv_mpfr_to_tree (mpc_realref (expr->value.complex),
expr->ts.kind, expr->is_snan);
tree imag = gfc_conv_mpfr_to_tree (mpc_imagref (expr->value.complex),
expr->ts.kind, expr->is_snan);
return build_complex (gfc_typenode_for_spec (&expr->ts),
real, imag);
}
case BT_CHARACTER:
res = gfc_build_wide_string_const (expr->ts.kind,
expr->value.character.length,
expr->value.character.string);
return res;
case BT_HOLLERITH:
return gfc_build_string_const (expr->representation.length,
expr->representation.string);
default:
fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
gfc_typename (&expr->ts));
}
}
示例11: build_throw
//.........这里部分代码省略.........
exp_vec = make_tree_vector_single (moved);
moved = (build_special_member_call
(object, complete_ctor_identifier, &exp_vec,
TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE,
tf_none));
release_tree_vector (exp_vec);
if (moved != error_mark_node)
{
exp = moved;
converted = true;
}
}
/* Call the copy constructor. */
if (!converted)
{
exp_vec = make_tree_vector_single (exp);
exp = (build_special_member_call
(object, complete_ctor_identifier, &exp_vec,
TREE_TYPE (object), flags, tf_warning_or_error));
release_tree_vector (exp_vec);
}
if (exp == error_mark_node)
{
error (" in thrown expression");
return error_mark_node;
}
}
else
{
tmp = decay_conversion (exp, tf_warning_or_error);
if (tmp == error_mark_node)
return error_mark_node;
exp = build2 (INIT_EXPR, temp_type, object, tmp);
}
/* Mark any cleanups from the initialization as MUST_NOT_THROW, since
they are run after the exception object is initialized. */
cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0);
/* Prepend the allocation. */
exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
/* Force all the cleanups to be evaluated here so that we don't have
to do them during unwinding. */
exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp);
throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
cleanup = NULL_TREE;
if (type_build_dtor_call (TREE_TYPE (object)))
{
tree dtor_fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
complete_dtor_identifier, 0);
dtor_fn = BASELINK_FUNCTIONS (dtor_fn);
mark_used (dtor_fn);
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
{
cxx_mark_addressable (dtor_fn);
/* Pretend it's a normal function. */
cleanup = build1 (ADDR_EXPR, cleanup_type, dtor_fn);
}
}
if (cleanup == NULL_TREE)
cleanup = build_int_cst (cleanup_type, 0);
/* ??? Indicate that this function call throws throw_type. */
tmp = cp_build_function_call_nary (throw_fn, tf_warning_or_error,
ptr, throw_type, cleanup, NULL_TREE);
/* Tack on the initialization stuff. */
exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
}
else
{
/* Rethrow current exception. */
if (!rethrow_fn)
{
tree name = get_identifier ("__cxa_rethrow");
rethrow_fn = get_global_binding (name);
if (!rethrow_fn)
/* Declare void __cxa_rethrow (void). */
rethrow_fn = push_throw_library_fn
(name, build_function_type_list (void_type_node, NULL_TREE));
if (flag_tm)
apply_tm_attr (rethrow_fn, get_identifier ("transaction_pure"));
}
/* ??? Indicate that this function call allows exceptions of the type
of the enclosing catch block (if known). */
exp = cp_build_function_call_vec (rethrow_fn, NULL, tf_warning_or_error);
}
exp = build1 (THROW_EXPR, void_type_node, exp);
SET_EXPR_LOCATION (exp, input_location);
return exp;
}
示例12: ifcombine_ifandif
static bool
ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
{
gimple_stmt_iterator gsi;
gimple inner_cond, outer_cond;
tree name1, name2, bit1, bit2;
inner_cond = last_stmt (inner_cond_bb);
if (!inner_cond
|| gimple_code (inner_cond) != GIMPLE_COND)
return false;
outer_cond = last_stmt (outer_cond_bb);
if (!outer_cond
|| gimple_code (outer_cond) != GIMPLE_COND)
return false;
/* See if we test a single bit of the same name in both tests. In
that case remove the outer test, merging both else edges,
and change the inner one to test for
name & (bit1 | bit2) == (bit1 | bit2). */
if (recognize_single_bit_test (inner_cond, &name1, &bit1)
&& recognize_single_bit_test (outer_cond, &name2, &bit2)
&& name1 == name2)
{
tree t, t2;
/* Do it. */
gsi = gsi_for_stmt (inner_cond);
t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
build_int_cst (TREE_TYPE (name1), 1), bit1);
t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
build_int_cst (TREE_TYPE (name1), 1), bit2);
t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
true, GSI_SAME_STMT);
t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
true, GSI_SAME_STMT);
t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
update_stmt (outer_cond);
if (dump_file)
{
fprintf (dump_file, "optimizing double bit test to ");
print_generic_expr (dump_file, name1, 0);
fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
print_generic_expr (dump_file, bit1, 0);
fprintf (dump_file, ") | (1 << ");
print_generic_expr (dump_file, bit2, 0);
fprintf (dump_file, ")\n");
}
return true;
}
return false;
}
示例13: recognize_single_bit_test
static bool
recognize_single_bit_test (gimple cond, tree *name, tree *bit)
{
gimple stmt;
/* Get at the definition of the result of the bit test. */
if (gimple_cond_code (cond) != NE_EXPR
|| TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
|| !integer_zerop (gimple_cond_rhs (cond)))
return false;
stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
if (!is_gimple_assign (stmt))
return false;
/* Look at which bit is tested. One form to recognize is
D.1985_5 = state_3(D) >> control1_4(D);
D.1986_6 = (int) D.1985_5;
D.1987_7 = op0 & 1;
if (D.1987_7 != 0) */
if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
&& integer_onep (gimple_assign_rhs2 (stmt))
&& TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
tree orig_name = gimple_assign_rhs1 (stmt);
/* Look through copies and conversions to eventually
find the stmt that computes the shift. */
stmt = SSA_NAME_DEF_STMT (orig_name);
while (is_gimple_assign (stmt)
&& ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
&& (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
<= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
|| gimple_assign_ssa_name_copy_p (stmt)))
stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
/* If we found such, decompose it. */
if (is_gimple_assign (stmt)
&& gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
{
/* op0 & (1 << op1) */
*bit = gimple_assign_rhs2 (stmt);
*name = gimple_assign_rhs1 (stmt);
}
else
{
/* t & 1 */
*bit = integer_zero_node;
*name = get_name_for_bit_test (orig_name);
}
return true;
}
/* Another form is
D.1987_7 = op0 & (1 << CST)
if (D.1987_7 != 0) */
if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
&& TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
&& integer_pow2p (gimple_assign_rhs2 (stmt)))
{
*name = gimple_assign_rhs1 (stmt);
*bit = build_int_cst (integer_type_node,
tree_log2 (gimple_assign_rhs2 (stmt)));
return true;
}
/* Another form is
D.1986_6 = 1 << control1_4(D)
D.1987_7 = op0 & D.1986_6
if (D.1987_7 != 0) */
if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
&& TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
&& TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
{
gimple tmp;
/* Both arguments of the BIT_AND_EXPR can be the single-bit
specifying expression. */
tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
if (is_gimple_assign (tmp)
&& gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
&& integer_onep (gimple_assign_rhs1 (tmp)))
{
*name = gimple_assign_rhs2 (stmt);
*bit = gimple_assign_rhs2 (tmp);
return true;
}
tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
if (is_gimple_assign (tmp)
&& gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
&& integer_onep (gimple_assign_rhs1 (tmp)))
{
*name = gimple_assign_rhs1 (stmt);
*bit = gimple_assign_rhs2 (tmp);
return true;
}
}
//.........这里部分代码省略.........
示例14: ubsan_maybe_instrument_reference_or_call
static tree
ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
enum ubsan_null_ckind ckind)
{
if (!do_ubsan_in_current_function ())
return NULL_TREE;
tree type = TREE_TYPE (ptype);
tree orig_op = op;
bool instrument = false;
unsigned int mina = 0;
if (flag_sanitize & SANITIZE_ALIGNMENT)
{
mina = min_align_of_type (type);
if (mina <= 1)
mina = 0;
}
while ((TREE_CODE (op) == NOP_EXPR
|| TREE_CODE (op) == NON_LVALUE_EXPR)
&& TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
op = TREE_OPERAND (op, 0);
if (TREE_CODE (op) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
{
if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
instrument = true;
}
else
{
if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
{
bool strict_overflow_p = false;
/* tree_single_nonzero_warnv_p will not return true for non-weak
non-automatic decls with -fno-delete-null-pointer-checks,
which is disabled during -fsanitize=null. We don't want to
instrument those, just weak vars though. */
int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks;
flag_delete_null_pointer_checks = 1;
if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p)
|| strict_overflow_p)
instrument = true;
flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks;
}
else if (flag_sanitize & SANITIZE_NULL)
instrument = true;
if (mina && mina > 1)
{
if (!POINTER_TYPE_P (TREE_TYPE (op))
|| mina > get_pointer_alignment (op) / BITS_PER_UNIT)
instrument = true;
}
}
if (!instrument)
return NULL_TREE;
op = save_expr (orig_op);
gcc_assert (POINTER_TYPE_P (ptype));
if (TREE_CODE (ptype) == REFERENCE_TYPE)
ptype = build_pointer_type (TREE_TYPE (ptype));
tree kind = build_int_cst (ptype, ckind);
tree align = build_int_cst (pointer_sized_int_node, mina);
tree call
= build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
3, op, kind, align);
TREE_SIDE_EFFECTS (call) = 1;
return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
}
示例15: ubsan_instrument_division
tree
ubsan_instrument_division (location_t loc, tree op0, tree op1)
{
tree t, tt;
tree type = TREE_TYPE (op0);
/* At this point both operands should have the same type,
because they are already converted to RESULT_TYPE.
Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
== TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
op0 = unshare_expr (op0);
op1 = unshare_expr (op1);
if (TREE_CODE (type) == INTEGER_TYPE
&& (flag_sanitize & SANITIZE_DIVIDE))
t = fold_build2 (EQ_EXPR, boolean_type_node,
op1, build_int_cst (type, 0));
else if (TREE_CODE (type) == REAL_TYPE
&& (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
t = fold_build2 (EQ_EXPR, boolean_type_node,
op1, build_real (type, dconst0));
else
return NULL_TREE;
/* We check INT_MIN / -1 only for signed types. */
if (TREE_CODE (type) == INTEGER_TYPE
&& (flag_sanitize & SANITIZE_DIVIDE)
&& !TYPE_UNSIGNED (type))
{
tree x;
tt = fold_build2 (EQ_EXPR, boolean_type_node, unshare_expr (op1),
build_int_cst (type, -1));
x = fold_build2 (EQ_EXPR, boolean_type_node, op0,
TYPE_MIN_VALUE (type));
x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
}
/* If the condition was folded to 0, no need to instrument
this expression. */
if (integer_zerop (t))
return NULL_TREE;
/* In case we have a SAVE_EXPR in a conditional context, we need to
make sure it gets evaluated before the condition. */
t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), unshare_expr (op0), t);
t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), unshare_expr (op1), t);
if (flag_sanitize_undefined_trap_on_error)
tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
else
{
tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
ubsan_type_descriptor (type), NULL_TREE,
NULL_TREE);
data = build_fold_addr_expr_loc (loc, data);
enum built_in_function bcode
= (flag_sanitize_recover & SANITIZE_DIVIDE)
? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
: BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
tt = builtin_decl_explicit (bcode);
op0 = unshare_expr (op0);
op1 = unshare_expr (op1);
tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
ubsan_encode_value (op1));
}
t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
return t;
}