diff options
Diffstat (limited to 'gcc/cp/semantics.cc')
-rw-r--r-- | gcc/cp/semantics.cc | 87 |
1 files changed, 33 insertions, 54 deletions
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 30cf2f9..7d46c3c 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2519,6 +2519,10 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr) /* Update for array-to-pointer decay. */ type = TREE_TYPE (expr); + /* This TARGET_EXPR will initialize the outer one added by + finish_stmt_expr. */ + set_target_expr_eliding (expr); + /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a normal statement, but don't convert to void or actually add the EXPR_STMT. */ @@ -4668,7 +4672,7 @@ simplify_aggr_init_expr (tree *tp) expand_call{,_inline}. */ cxx_mark_addressable (slot); CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true; - call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr); + call_expr = cp_build_init_expr (slot, call_expr); } else if (style == pcc) { @@ -4687,7 +4691,7 @@ simplify_aggr_init_expr (tree *tp) { tree init = build_zero_init (type, NULL_TREE, /*static_storage_p=*/false); - init = build2 (INIT_EXPR, void_type_node, slot, init); + init = cp_build_init_expr (slot, init); call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr), init, call_expr); } @@ -4882,7 +4886,7 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data) tree init; if (DECL_INITIAL (dp->var) && DECL_INITIAL (dp->var) != error_mark_node) - init = build2 (INIT_EXPR, void_type_node, dp->result, + init = cp_build_init_expr (dp->result, DECL_INITIAL (dp->var)); else init = build_empty_stmt (EXPR_LOCATION (*tp)); @@ -6426,7 +6430,7 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) else init = fold_convert (TREE_TYPE (v), integer_zero_node); OMP_CLAUSE_REDUCTION_INIT (c) - = build2 (INIT_EXPR, TREE_TYPE (v), v, init); + = cp_build_init_expr (v, init); } } } @@ -11172,42 +11176,31 @@ init_cp_semantics (void) } -/* If we have a condition in conjunctive normal form (CNF), find the first - failing clause. In other words, given an expression like - - true && true && false && true && false +/* Emit additional diagnostics for failing condition BAD. + Used by finish_static_assert and IFN_ASSUME constexpr diagnostics. + If SHOW_EXPR_P is true, print the condition (because it was + instantiation-dependent). */ - return the first 'false'. EXPR is the expression. */ - -static tree -find_failing_clause_r (tree expr) +void +diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p) { - if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR) + /* Nobody wants to see the artificial (bool) cast. */ + bad = tree_strip_nop_conversions (bad); + + /* Actually explain the failure if this is a concept check or a + requires-expression. */ + if (concept_check_p (bad) || TREE_CODE (bad) == REQUIRES_EXPR) + diagnose_constraints (cloc, bad, NULL_TREE); + else if (COMPARISON_CLASS_P (bad) + && ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))) { - /* First check the left side... */ - tree e = find_failing_clause_r (TREE_OPERAND (expr, 0)); - if (e == NULL_TREE) - /* ...if we didn't find a false clause, check the right side. */ - e = find_failing_clause_r (TREE_OPERAND (expr, 1)); - return e; + tree op0 = fold_non_dependent_expr (TREE_OPERAND (bad, 0)); + tree op1 = fold_non_dependent_expr (TREE_OPERAND (bad, 1)); + tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1); + inform (cloc, "the comparison reduces to %qE", cond); } - tree e = contextual_conv_bool (expr, tf_none); - e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true); - if (integer_zerop (e)) - /* This is the failing clause. */ - return expr; - return NULL_TREE; -} - -/* Wrapper for find_failing_clause_r. */ - -static tree -find_failing_clause (tree expr) -{ - if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR) - if (tree e = find_failing_clause_r (expr)) - expr = e; - return expr; + else if (show_expr_p) + inform (cloc, "%qE evaluates to false", bad); } /* Build a STATIC_ASSERT for a static assertion with the condition @@ -11274,12 +11267,12 @@ finish_static_assert (tree condition, tree message, location_t location, int len = TREE_STRING_LENGTH (message) / sz - 1; /* See if we can find which clause was failing (for logical AND). */ - tree bad = find_failing_clause (orig_condition); + tree bad = find_failing_clause (NULL, orig_condition); /* If not, or its location is unusable, fall back to the previous location. */ location_t cloc = cp_expr_loc_or_loc (bad, location); - /* Nobody wants to see the artificial (bool) cast. */ - bad = tree_strip_nop_conversions (bad); + + auto_diagnostic_group d; /* Report the error. */ if (len == 0) @@ -11288,21 +11281,7 @@ finish_static_assert (tree condition, tree message, location_t location, error_at (cloc, "static assertion failed: %s", TREE_STRING_POINTER (message)); - /* Actually explain the failure if this is a concept check or a - requires-expression. */ - if (concept_check_p (bad) - || TREE_CODE (bad) == REQUIRES_EXPR) - diagnose_constraints (location, bad, NULL_TREE); - else if (COMPARISON_CLASS_P (bad) - && ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))) - { - tree op0 = fold_non_dependent_expr (TREE_OPERAND (bad, 0)); - tree op1 = fold_non_dependent_expr (TREE_OPERAND (bad, 1)); - tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1); - inform (cloc, "the comparison reduces to %qE", cond); - } - else if (show_expr_p) - inform (cloc, "%qE evaluates to false", bad); + diagnose_failing_condition (bad, cloc, show_expr_p); } else if (condition && condition != error_mark_node) { |