aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cvt.c
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2015-11-13 19:08:05 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-11-13 19:08:05 -0500
commitcda0a029f45d20f4535dcacf6c3194352c31e736 (patch)
treee5f2d64459601fae812cfe90245af2831eebedb1 /gcc/cp/cvt.c
parent8fe17e23b052741c8cbec99c7173c3c07f8e8c64 (diff)
downloadgcc-cda0a029f45d20f4535dcacf6c3194352c31e736.zip
gcc-cda0a029f45d20f4535dcacf6c3194352c31e736.tar.gz
gcc-cda0a029f45d20f4535dcacf6c3194352c31e736.tar.bz2
Merge C++ delayed folding branch.
* call.c (build_conditional_expr_1, convert_like_real) (convert_arg_to_ellipsis, convert_for_arg_passing): Don't fold. (build_new_op_1, build_over_call, build_cxx_call): Fold for warnings. * class.c (build_base_path, determine_primary_bases) (update_vtable_entry_for_fn, check_bitfield_decl) (layout_nonempty_base_or_field, layout_empty_base) (propagate_binfo_offsets, include_empty_classes) (layout_class_type, build_vbase_offset_vtbl_entries): Use fold_convert. * constexpr.c (cxx_eval_builtin_function_call): Fold away the NOP_EXPR. (cxx_eval_call_expression): Handle MEM_REF. (cxx_eval_pointer_plus_expression): Fold the second operand. (cxx_eval_constant_expression): Handle MEM_REF, UNARY_PLUS_EXPR. (fold_simple_1, fold_simple): New. (maybe_constant_value_1): Factor out from maybe_constant_value. (cv_cache, maybe_constant_value): Cache results. (maybe_constant_init): Handle null input. (potential_constant_expression_1): Handle RESULT_DECL, EMPTY_CLASS_EXPR. * cp-array-notation.c (build_array_notation_ref): Fold operands. * cp-gimplify.c (cp_fold_r, cp_fold): New. (cp_genericize_r): Use fold_convert. Don't fold SIZEOF_EXPR. (cp_genericize): Fold everything. (contains_label_1, contains_label_p): New. (cp_fold, cp_fully_fold): New. * cp-tree.h (class cache_map): New. * cvt.c (cp_convert_to_pointer, ocp_convert): Use convert_to_*_nofold. (cp_convert_and_check): Use cp_fully_fold. (convert, convert_force): Don't fold. * decl.c (fold_sizeof_expr): Change from fold_sizeof_expr_r. (compute_array_index_type): Use cp_fully_fold. (build_enumerator): Use fold_convert. * decl2.c (get_guard_cond, set_guard): Use fold_convert. * init.c (build_zero_init_1): Fold zero-initializers. (build_new_1): Fold nelts calculations. (build_vec_delete_1): Fold conversions. (build_vec_init): Fold maxindex. * parser.c (cp_parser_binary_expression): Fold LHS of || and &&. (cp_parser_question_colon_clause): Fold LHS. * pt.c (convert_nontype_argument): Fold nullptr conversion. * semantics.c (finish_unary_op_expr): Fold for warnings. (handle_omp_array_sections_1): Fold length and low bound. (handle_omp_for_class_iterator): Fold various things. * tree.c (builtin_valid_in_constant_expr_p): Add BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE. (convert_bitfield_to_declared_type): Don't fold. (handle_init_priority_attribute): Fold. (fold_if_not_in_template): Remove. * typeck.c (decay_conversion, build_class_member_access_expr) (build_simple_component_ref, cp_build_array_ref, build_vec_cmp) (cp_pointer_int_sum, pointer_diff): Don't fold. (cp_build_binary_op): Fold for warnings and PMF ops. (cp_build_unary_op): Fold negation of a constant, nothing else. (expand_ptrmemfunc_cst): Fold operations. * typeck2.c (split_nonconstant_init): Fold initializer. (store_init_value): Likewise. (check_narrowing): Try folding. * config-lang.in (gtfiles): Add cp-gimplify.c. From-SVN: r230365
Diffstat (limited to 'gcc/cp/cvt.c')
-rw-r--r--gcc/cp/cvt.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index c6e13f3..0231efc 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -50,7 +50,7 @@ static void diagnose_ref_binding (location_t, tree, tree, tree);
Here is a list of all the functions that assume that widening and
narrowing is always done with a NOP_EXPR:
- In convert.c, convert_to_integer.
+ In convert.c, convert_to_integer[_nofold].
In c-typeck.c, build_binary_op_nodefault (boolean ops),
and c_common_truthvalue_conversion.
In expr.c: expand_expr, for operands of a MULT_EXPR.
@@ -237,7 +237,7 @@ cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain)
gcc_assert (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
== GET_MODE_SIZE (TYPE_MODE (type)));
- return convert_to_pointer (type, expr);
+ return convert_to_pointer_nofold (type, expr);
}
if (type_unknown_p (expr))
@@ -630,22 +630,25 @@ cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
if (TREE_TYPE (expr) == type)
return expr;
-
+ if (expr == error_mark_node)
+ return expr;
result = cp_convert (type, expr, complain);
if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0)
{
- tree folded = maybe_constant_value (expr);
- tree stripped = folded;
- tree folded_result
- = folded != expr ? cp_convert (type, folded, complain) : result;
-
- /* maybe_constant_value wraps an INTEGER_CST with TREE_OVERFLOW in a
- NOP_EXPR so that it isn't TREE_CONSTANT anymore. */
- STRIP_NOPS (stripped);
-
- if (!TREE_OVERFLOW_P (stripped)
+ tree folded = cp_fully_fold (expr);
+ tree folded_result;
+ if (folded == expr)
+ folded_result = result;
+ else
+ {
+ /* Avoid bogus -Wparentheses warnings. */
+ TREE_NO_WARNING (folded) = true;
+ folded_result = cp_convert (type, folded, tf_none);
+ }
+ folded_result = fold_simple (folded_result);
+ if (!TREE_OVERFLOW_P (folded)
&& folded_result != error_mark_node)
warnings_for_convert_and_check (input_location, type, folded,
folded_result);
@@ -703,9 +706,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
/* For complex data types, we need to perform componentwise
conversion. */
else if (TREE_CODE (type) == COMPLEX_TYPE)
- return fold_if_not_in_template (convert_to_complex (type, e));
+ return convert_to_complex_nofold (type, e);
else if (VECTOR_TYPE_P (type))
- return fold_if_not_in_template (convert_to_vector (type, e));
+ return convert_to_vector (type, e);
else if (TREE_CODE (e) == TARGET_EXPR)
{
/* Don't build a NOP_EXPR of class type. Instead, change the
@@ -718,7 +721,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
/* We shouldn't be treating objects of ADDRESSABLE type as
rvalues. */
gcc_assert (!TREE_ADDRESSABLE (type));
- return fold_if_not_in_template (build_nop (type, e));
+ return build_nop (type, e);
}
}
@@ -796,7 +799,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
return cp_truthvalue_conversion (e);
}
- converted = fold_if_not_in_template (convert_to_integer (type, e));
+ converted = convert_to_integer_nofold (type, e);
/* Ignore any integer overflow caused by the conversion. */
return ignore_overflows (converted, e);
@@ -808,7 +811,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
return nullptr_node;
}
if (POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type))
- return fold_if_not_in_template (cp_convert_to_pointer (type, e, complain));
+ return cp_convert_to_pointer (type, e, complain);
if (code == VECTOR_TYPE)
{
tree in_vtype = TREE_TYPE (e);
@@ -823,7 +826,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
in_vtype, type);
return error_mark_node;
}
- return fold_if_not_in_template (convert_to_vector (type, e));
+ return convert_to_vector (type, e);
}
if (code == REAL_TYPE || code == COMPLEX_TYPE)
{
@@ -839,9 +842,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
TREE_TYPE (e));
}
if (code == REAL_TYPE)
- return fold_if_not_in_template (convert_to_real (type, e));
+ return convert_to_real_nofold (type, e);
else if (code == COMPLEX_TYPE)
- return fold_if_not_in_template (convert_to_complex (type, e));
+ return convert_to_complex_nofold (type, e);
}
/* New C++ semantics: since assignment is now based on
@@ -1454,7 +1457,7 @@ convert (tree type, tree expr)
intype = TREE_TYPE (expr);
if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))
- return fold_if_not_in_template (build_nop (type, expr));
+ return build_nop (type, expr);
return ocp_convert (type, expr, CONV_OLD_CONVERT,
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
@@ -1472,13 +1475,11 @@ convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain)
enum tree_code code = TREE_CODE (type);
if (code == REFERENCE_TYPE)
- return (fold_if_not_in_template
- (convert_to_reference (type, e, CONV_C_CAST, 0,
- NULL_TREE, complain)));
+ return convert_to_reference (type, e, CONV_C_CAST, 0,
+ NULL_TREE, complain);
if (code == POINTER_TYPE)
- return fold_if_not_in_template (convert_to_pointer_force (type, e,
- complain));
+ return convert_to_pointer_force (type, e, complain);
/* From typeck.c convert_for_assignment */
if (((TYPE_PTR_P (TREE_TYPE (e)) && TREE_CODE (e) == ADDR_EXPR