This is the mail archive of the
`gcc-patches@gcc.gnu.org`
mailing list for the GCC project.

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |

Other format: | [Raw text] |

*From*: Jason Merrill <jason at redhat dot com>*To*: Kai Tietz <ktietz70 at googlemail dot com>*Cc*: gcc-patches List <gcc-patches at gcc dot gnu dot org>*Date*: Fri, 24 Apr 2015 00:22:49 -0400*Subject*: C++ delayed folding branch review*Authentication-results*: sourceware.org; auth=none

+ expr = fold (expr); /* This may happen, because for LHS op= RHS we preevaluate RHS and create C_MAYBE_CONST_EXPR <SAVE_EXPR <RHS>>, which means we could no longer see the code of the EXPR. */ if (TREE_CODE (expr) == C_MAYBE_CONST_EXPR) expr = C_MAYBE_CONST_EXPR_EXPR (expr); if (TREE_CODE (expr) == SAVE_EXPR) - expr = TREE_OPERAND (expr, 0); + expr = fold (TREE_OPERAND (expr, 0));

+ case NEGATE_EXPR: + case BIT_NOT_EXPR: + case CONVERT_EXPR: + case VIEW_CONVERT_EXPR: + case NOP_EXPR: + case FIX_TRUNC_EXPR: + { + tree op1 = TREE_OPERAND (expr, 0); + tree fop1 = fold (op1); + if (fop1 && op1 != fop1) + fop1 = fold_build1_loc (loc, TREE_CODE (expr), TREE_TYPE (expr), + fop1);

@@ -597,9 +597,9 @@ null_member_pointer_value_p (tree t) return false; else if (TYPE_PTRMEMFUNC_P (type)) return (TREE_CODE (t) == CONSTRUCTOR - && integer_zerop (CONSTRUCTOR_ELT (t, 0)->value)); + && integer_zerop (fold (CONSTRUCTOR_ELT (t, 0)->value))); else if (TYPE_PTRDATAMEM_P (type)) - return integer_all_onesp (t); + return integer_all_onesp (fold (t));

warn_logical_operator (loc, code, boolean_type_node, - code_orig_arg1, arg1, - code_orig_arg2, arg2); + code_orig_arg1, fold (arg1), + code_orig_arg2, fold (arg2));

@@ -7356,8 +7354,13 @@ build_over_call (struct z_candidate *cand, int flags, tsu bst_flags_t complain) gcc_assert (j <= nargs); nargs = j; + { + tree *fargs = (!nargs ? argarray : (tree *) alloca (nargs * sizeof (tree))) ; + for (j = 0; j < nargs; j++) + fargs[j] = fold_non_dependent_expr (argarray[j]);

Similarly, this and build_cxx_call should use cp_fully_fold.

@@ -7602,7 +7614,6 @@ build_cxx_call (tree fn, int nargs, tree *argarray, && current_function_decl && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) optimize = 1; - fn = fold_if_not_in_template (fn); optimize = optimize_sav;

Since we're removing the fold, we can also remove the changes to "optimize".

@@ -443,7 +443,7 @@ build_base_path (enum tree_code code, t = TREE_TYPE (TYPE_VFIELD (current_class_type)); t = build_pointer_type (t); - v_offset = convert (t, current_vtt_parm); + v_offset = fold (convert (t, current_vtt_parm));

fold_convert should work here.

@@ -576,7 +576,6 @@ build_simple_base_path (tree expr, tree binfo) expr = build3 (COMPONENT_REF, cp_build_qualified_type (type, type_quals), expr, field, NULL_TREE); - expr = fold_if_not_in_template (expr);

@@ -1046,6 +1048,9 @@ adjust_temp_type (tree type, tree temp) { if (TREE_TYPE (temp) == type) return temp; + STRIP_NOPS (temp); + if (TREE_TYPE (temp) == type) + return temp;

...

reduced_constant_expression_p (tree t) { + /* Make sure we remove useless initial NOP_EXPRs. */ + STRIP_NOPS (t);

Where are these NOPs coming from?

@@ -1082,7 +1087,10 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, && is_dummy_object (x)) { x = ctx->object; - x = cp_build_addr_expr (x, tf_warning_or_error); + if (x) + x = cp_build_addr_expr (x, tf_warning_or_error); + else + x = get_nth_callarg (t, i);

This should not be necessary.

@@ -1765,7 +1780,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, if (field == part) { if (value) - return value; + return cxx_eval_constant_expression (ctx, value, lval, + non_constant_p, overflow_p);

...

@@ -1849,7 +1865,8 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t, { tree bitpos = bit_position (field); if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1)) - return value; + return cxx_eval_constant_expression (ctx, value, lval, + non_constant_p, overflow_p);

@@ -1560,14 +1570,19 @@ cxx_eval_unary_expression (const constexpr_ctx *ctx, tre e t, location_t loc = EXPR_LOCATION (t); enum tree_code code = TREE_CODE (t); tree type = TREE_TYPE (t); - r = fold_unary_loc (loc, code, type, arg); - if (r == NULL_TREE) + if (TREE_CODE (t) == UNARY_PLUS_EXPR) + r = fold_convert_loc (loc, TREE_TYPE (t), arg);

case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: case FIXED_CONVERT_EXPR: + case UNARY_PLUS_EXPR: r = cxx_eval_unary_expression (ctx, t, lval,

So this case should be down with NOP_EXPR.

@@ -2954,19 +2987,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, constexpr_ctx new_ctx; tree r = t; - if (t == error_mark_node) + if (!t || t == error_mark_node)

Where are null expressions coming from?

case SIZEOF_EXPR: + if (processing_template_decl + && (!COMPLETE_TYPE_P (TREE_TYPE (t)) + || TREE_CODE (TYPE_SIZE (TREE_TYPE (t))) != INTEGER_CST)) + return t;

+ /* See this can happen for case like g++.dg/init/static2.C testcase. */ + if (!ctx || !ctx->ctor || (lval && !ctx->object) + || !same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (t), TREE_TYPE (ctx->ctor)) + || CONSTRUCTOR_NELTS (ctx->ctor) != 0) + { + *non_constant_p = true; + break; + }

case NOP_EXPR: { tree oldop = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == NOP_EXPR && TREE_TYPE (t) == TREE_TYPE (oldop) && TREE_OVERFLOW_P (oldop)) + { + if (!ctx->quiet) + permerror (input_location, "overflow in constant expression"); + /* If we're being permissive (and are in an enforcing + context), ignore the overflow. */ + if (!flag_permissive) + *overflow_p = true; + *non_constant_p = true; + + return t; + }

maybe_constant_init (tree t, tree decl) { + if (!t) + return t;

Where are null initializers coming from?

case MINUS_EXPR: /* -- a subtraction where both operands are pointers. */ if (TYPE_PTR_P (TREE_OPERAND (t, 0)) - && TYPE_PTR_P (TREE_OPERAND (t, 1))) + && TYPE_PTR_P (TREE_OPERAND (t, 1)) + && TREE_OPERAND (t, 0) != TREE_OPERAND (t, 1))

Why? From where are we getting a pointer subtracted from itself?

+static tree +cp_fold (tree x, hash_map<tree, tree> *fold_hash) +{

....

@@ -614,9 +614,13 @@ cp_fold_convert (tree type, tree expr) } else { - conv = fold_convert (type, expr); + if (TREE_CODE (expr) == INTEGER_CST) + conv = fold_convert (type, expr); + else + conv = convert (type, expr);

cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain) { - tree result; + tree result, ret; if (TREE_TYPE (expr) == type) return expr; - result = cp_convert (type, expr, complain); + result = ret = cp_convert (type, expr, complain); if ((complain & tf_warning) && c_inhibit_evaluation_warnings == 0) @@ -652,6 +656,7 @@ cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain) tree stripped = folded; tree folded_result = folded != expr ? cp_convert (type, folded, complain) : result; + folded_result = fold (folded_result); /* maybe_constant_value wraps an INTEGER_CST with TREE_OVERFLOW in a NOP_EXPR so that it isn't TREE_CONSTANT anymore. */ @@ -663,7 +668,7 @@ cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain) folded_result); } - return result; + return ret;

@@ -1535,8 +1538,10 @@ build_expr_type_conversion (int desires, tree expr, bool complain) + tree expr_folded = maybe_constant_value (expr); - if (expr == null_node + STRIP_NOPS (expr_folded); + if (expr_folded == null_node

@@ -8502,16 +8502,18 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) + /* We need to do fully folding to determine if we have VLA, or not. */ + tree size_constant = maybe_constant_value (size);

- itype = fold (itype); + itype = maybe_constant_value (itype); - itype = variable_size (fold (newitype)); + itype = variable_size (maybe_constant_value (newitype));

Maybe these should use cp_fully_fold?

@@ -13090,6 +13092,8 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc) + if (value) + value = maybe_constant_value (value);

This seems unnecessary, since we call cxx_constant_value below.

value = cxx_constant_value (value); + STRIP_NOPS (value);

- value = convert (ENUM_UNDERLYING_TYPE (enumtype), value); + value = fold (convert (ENUM_UNDERLYING_TYPE (enumtype), value));

fold_convert again.

@@ -188,9 +188,9 @@ build_zero_init_1 (tree type, tree nelts, bool static_storage_p, - init = convert (type, nullptr_node); + init = fold (convert (type, nullptr_node));

fold_convert

@@ -783,7 +783,8 @@ perform_member_init (tree member, tree init) + if (init) + init = fold (init);

Why fold here? This doesn't seem like a place that needs early folding.

@@ -6480,7 +6480,8 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index, - *init_index = cp_parser_expression (parser); + *init_index = cp_parser_expression (parser); + *init_index = maybe_constant_value (*init_index);

...

+ length_index = maybe_constant_value (length_index);

...

+ stride = maybe_constant_value (stride);

+ /* For offsetof and declaration of types we need + constant integeral values. + Also we meed to fold for negative constants so that diagnostic in + c-family/c-common.c doesn't fail for array-bounds. */ + if (for_offsetof || decltype_p + || (TREE_CODE (index) == NEGATE_EXPR && TREE_CODE (TREE_OPERAND (index, 0)) == INTEGER_CST)) + index = maybe_constant_value (index);

@@ -9876,6 +9888,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes) + expr = maybe_constant_value (expr);

This seems redundant with the call to cxx_constant_value in case_conversion.

@@ -12190,6 +12204,10 @@ cp_parser_static_assert(cp_parser *parser, bool member_p) + /* Make sure we folded it completely before doing trying to get + constant value. */ + condition = fold_non_dependent_expr (condition);

@@ -16081,6 +16099,7 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type) + value = maybe_constant_value (value);

+ width = maybe_constant_value (width);

@@ -449,7 +449,7 @@ build_aggr_init_expr (tree type, tree init) - return convert (type, init); + return fold (convert (type, init));

fold_convert

@@ -3394,6 +3394,8 @@ handle_init_priority_attribute (tree* node, + if (initp_expr) + initp_expr = maybe_constant_value (initp_expr);

@@ -3371,7 +3367,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, - e2 = fold_convert (TREE_TYPE (e3), e2); + e2 = fold (convert (TREE_TYPE (e3), e2));

Why?

@@ -3667,6 +3663,10 @@ convert_arguments (tree typelist, vec<tree, va_gc> **valu + /* For BUILT_IN_NORMAL we want to fold constants. */ + if (fndecl && DECL_BUILT_IN (fndecl) + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + val = fold (val);

This should be cp_fully_fold, and lower down, after all the conversions.

- tree xop0 = op0, xop1 = op1, xresult_type = result_type; + tree xop0 = fold (op0), xop1 = fold (op1), xresult_type = result_type;

- if (TREE_OVERFLOW_P (result) + op0 = fold_non_dependent_expr (op0); + op1 = fold_non_dependent_expr (op1); + STRIP_NOPS (op0); + STRIP_NOPS (op1); + result_ovl = fold_build2 (resultcode, build_type, op0, op1); + if (TREE_OVERFLOW_P (result_ovl) && !TREE_OVERFLOW_P (op0) && !TREE_OVERFLOW_P (op1)) - overflow_warning (location, result); + overflow_warning (location, result_ovl);

@@ -7983,7 +7978,6 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn) tree binfo = binfo_or_else (orig_class, fn_class); *delta = build2 (PLUS_EXPR, TREE_TYPE (*delta), *delta, BINFO_OFFSET (binfo)); - *delta = fold_if_not_in_template (*delta);

- gcc_assert (val1->v.val_unsigned == DWARF2_ADDR_SIZE); + gcc_assert (val1->v.val_unsigned + == (unsigned HOST_WIDE_INT) DWARF2_ADDR_SIZE);

We need to fix this warning so this change is unnecessary.

- gcc_assert (TREE_OPERAND (t, 0) == decl); + gcc_assert (TREE_OPERAND (t, 0) == decl || TREE_OPERAND (t, 1) == decl);

This change doesn't seem to have anything to do with delayed folding.

|| (gimple_omp_for_kind (for_stmt) - == GF_OMP_FOR_KIND_CILKFOR)); + == GF_OMP_FOR_KIND_CILKFOR) + || (gimple_omp_for_kind (for_stmt) + == GF_OMP_FOR_KIND_FOR));

Nor this one.

+++ b/gcc/testsuite/g++.dg/ext/offsetof1.C +// { dg-options "-Wno-pointer-arith" }

+++ b/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C @@ -50,5 +50,5 @@ short mask5(int x) short mask6(short x) { - return x & -1; + return x & -1; // { dg-warning "conversion" }

This is also a false positive.

+++ b/gcc/testsuite/g++.dg/warn/skip-1.C -// Check that we don't warn about code that will not be executed. +// For delayed folding we will warn about code that will not be executed too.

This is not an improvement.

@@ -1791,6 +1791,9 @@ evaluate_stmt (gimple stmt) && (likelyvalue == CONSTANT || is_gimple_call (stmt) || (gimple_assign_single_p (stmt) && gimple_assign_rhs_code (stmt) == ADDR_EXPR)) + && (likelyvalue == CONSTANT || is_gimple_call (stmt) + || (gimple_assign_single_p (stmt) + && gimple_assign_rhs_code (stmt) == ADDR_EXPR))

Merge error?

@@ -1956,6 +1956,8 @@ build_complex (tree type, tree real, tree imag) { tree t = make_node (COMPLEX_CST); + real = fold (real); + imag = fold (imag);

@@ -5062,6 +5063,7 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset) while (TREE_CODE (local->val) == VIEW_CONVERT_EXPR || TREE_CODE (local->val) == NON_LVALUE_EXPR) local->val = TREE_OPERAND (local->val, 0); + local->val = fold (local->val);

Or here. Jason

**Follow-Ups**:**Re: C++ delayed folding branch review***From:*Kai Tietz

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |