diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 180 | ||||
-rw-r--r-- | gcc/cp/call.c | 24 | ||||
-rw-r--r-- | gcc/cp/class.c | 13 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 24 | ||||
-rw-r--r-- | gcc/cp/constraint.cc | 2 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.c | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 19 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/cp/error.c | 2 | ||||
-rw-r--r-- | gcc/cp/except.c | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 2 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 8 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 22 | ||||
-rw-r--r-- | gcc/cp/parser.c | 24 | ||||
-rw-r--r-- | gcc/cp/pt.c | 59 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 1 | ||||
-rw-r--r-- | gcc/cp/tree.c | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 3 |
19 files changed, 356 insertions, 58 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7c52edeeab6..58710a91787 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,183 @@ +2018-02-22 Jason Merrill <jason@redhat.com> + + PR c++/70468 - ICE with constructor delegation via typedef. + * pt.c (tsubst_initializer_list): Check for other mem-initializers + with constructor delegation. + +2018-02-22 Jason Merrill <jason@redhat.com> + + PR c++/84424 - ICE with constexpr and __builtin_shuffle. + * constexpr.c (reduced_constant_expression_p): Handle CONSTRUCTOR of + VECTOR_TYPE. + +2018-02-22 Marek Polacek <polacek@redhat.com> + + PR c++/84493 + * parser.c (cp_parser_braced_list): Use require_open instead of + consume_open. + +2018-02-21 Jason Merrill <jason@redhat.com> + + PR c++/84454 - ICE with pack expansion in signature. + * error.c (find_typenames_r): Also stop on EXPR_PACK_EXPANSION. + +2018-02-20 Siddhesh Poyarekar <siddhesh@sourceware.org> + + * cp-objcp-common.c (cxx_block_may_fallthru): Add case for + IF_STMT. + +2018-02-20 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/84446 + * parser.c (cp_parser_init_declarator): Don't call start_lambda_scope + on error_mark_node. + +2018-02-20 Jakub Jelinek <jakub@redhat.com> + + PR c++/84445 + * class.c (fixed_type_or_null) <case CALL_EXPR>: Only test + TREE_HAS_CONSTRUCTOR if instance is not an internal function call. + + PR c++/84449 + * tree.c (bot_manip): If build_cplus_new or break_out_target_exprs + returns error_mark_node, return it immediately. + (break_out_target_exprs): If cp_walk_tree with bot_manip returns + error_mark_node, return error_mark_node. + + PR c++/84455 + * pt.c (tsubst_lambda_expr): If not nested, increment temporarily + function_depth to avoid GC during finish_lambda_function. + +2018-02-19 Jason Merrill <jason@redhat.com> + + PR c++/84429 - ICE capturing VLA. + * lambda.c (build_capture_proxy): Handle reference refs. + +2018-02-19 Jakub Jelinek <jakub@redhat.com> + + PR c++/84448 + * parser.c (cp_parser_binary_expression): For no_toplevel_fold_p, if + either operand is error_mark_node, set current.lhs to that instead of + creating a binary op with error_mark_node operands. + + PR c++/84430 + * constexpr.c (potential_constant_expression_1): Handle OMP_SIMD. + +2018-02-19 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/84348 + * decl.c (grokdeclarator): Early return error_mark_node upon + ill-formed friend declaration. + +2018-02-16 Marek Polacek <polacek@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/84192 + * constexpr.c (cxx_eval_constant_expression) <case RETURN_EXPR>: Don't + set *jump_target to anything if jump_target is NULL. + +2018-02-16 Jason Merrill <jason@redhat.com> + + PR c++/84151 - unnecessary volatile load with static member. + * call.c (build_new_method_call_1): Avoid loading from a volatile + lvalue used as the object argument for a static member function. + + PR c++/81853 - using-directive and constexpr. + * constexpr.c (cxx_eval_constant_expression): Handle USING_STMT. + + PR c++/84420 - ICE with structured binding in lambda. + * lambda.c (is_capture_proxy): Check DECL_DECOMPOSITION_P. + + PR c++/83835 - C++17 error with constructor ctors. + * call.c (build_special_member_call): Set TARGET_EXPR_DIRECT_INIT_P. + + PR c++/82664 - ICE with reference to function template parm. + * pt.c (convert_nontype_argument_function): Avoid obfuscationg + NOP_EXPRs. + + PR c++/82764 - C++17 ICE with empty base + * class.c (build_base_field_1): Set DECL_SIZE to zero for empty base. + +2018-02-16 Jason Merrill <jason@redhat.com> + + PR c++/84421 - type-dependent if constexpr + * semantics.c (finish_if_stmt_cond): Check type_dependent_expression_p. + +2018-02-16 Nathan Sidwell <nathan@acm.org> + + Deprecate -ffriend-injection. + * decl.c (cxx_init_decl_processing): Emit warning on option. + * name-lookup.c (do_pushdecl): Emit warning if we push a visible + friend. + +2018-02-16 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/82468 + * decl.c (check_special_function_return_type): Reject template + template parameter in deduction guide. + +2018-02-16 Nathan Sidwell <nathan@acm.org> + + PR c++/84375 + * name-lookup.c (do_pushdecl): Bail out on bad local friend injection. + +2018-02-15 Jason Merrill <jason@redhat.com> + + PR c++/83227 - C++17 ICE with init-list derived-to-base conversion. + * call.c (convert_like_real): Don't use the copy-list-initialization + shortcut for ck_base. + + PR c++/84045 - ICE with typedef and noexcept. + * except.c (build_noexcept_spec): Use strip_typedefs_expr. + + PR c++/84376 - ICE with omitted template arguments. + * pt.c (dguide_name_p): Check for IDENTIFIER_NODE. + + PR c++/84368 - wrong error with local variable in variadic lambda. + * pt.c (tsubst_pack_expansion): Fix handling of non-packs in + local_specializations. + +2018-02-15 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/84330 + * constraint.cc (tsubst_constraint_info): Handle an error_mark_node + as first argument. + +2018-02-14 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/84350 + * pt.c (do_auto_deduction): Don't check the TREE_TYPE of a null + init, early return. + +2018-02-14 Nathan Sidwell <nathan@acm.org> + + * decl2.c (mark_vtable_entries): Set input_location to decl's. + (c_parse_final_cleanups): Restore input_location after emitting + vtables. + +2018-02-14 Paolo Carlini <paolo.carlini@oracle.com> + + * cp-tree.h (do_auto_deduction (tree, tree, tree)): Remove. + (do_auto_deduction (tree, tree, tree, tsubst_flags_t, + auto_deduction_context, tree, int): Add defaults. + * pt.c (do_auto_deduction (tree, tree, tree)): Remove definition. + (tsubst_omp_for_iterator): Adjust do_auto_deduction call, forward + tsubst_flags_t argument. + * init.c (build_new): Likewise. + +2018-02-13 Jakub Jelinek <jakub@redhat.com> + + PR c++/84364 + * typeck.c (check_return_expr): Don't emit -Weffc++ warning + about return other than *this in assignment operators if + retval is type dependent expression. + +2018-02-13 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/84333 + * call.c (build_conditional_expr_1): Use cp_save_expr instead of + save_expr for the G++ extension. + 2018-02-13 Jason Merrill <jason@redhat.com> PR c++/84080 - ICE with return type deduction and specialization. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 15b723ad2b0..7c93c6d8290 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4805,7 +4805,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3, if (lvalue_p (arg1)) arg2 = arg1 = cp_stabilize_reference (arg1); else - arg2 = arg1 = save_expr (arg1); + arg2 = arg1 = cp_save_expr (arg1); } /* If something has already gone wrong, just pass that fact up the @@ -6938,6 +6938,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, && DECL_INHERITED_CTOR (current_function_decl)) return expr; + if (TREE_CODE (expr) == TARGET_EXPR + && TARGET_EXPR_LIST_INIT_P (expr)) + /* Copy-list-initialization doesn't actually involve a copy. */ + return expr; + /* Fall through. */ case ck_base: if (convs->kind == ck_base && !convs->need_temporary_p) @@ -6964,10 +6969,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, if (convs->rvaluedness_matches_p) /* standard_conversion got LOOKUP_PREFER_RVALUE. */ flags |= LOOKUP_PREFER_RVALUE; - if (TREE_CODE (expr) == TARGET_EXPR - && TARGET_EXPR_LIST_INIT_P (expr)) - /* Copy-list-initialization doesn't actually involve a copy. */ - return expr; expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && complain) { @@ -8833,6 +8834,9 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args, { if (is_dummy_object (instance)) return arg; + else if (TREE_CODE (arg) == TARGET_EXPR) + TARGET_EXPR_DIRECT_INIT_P (arg) = true; + if ((complain & tf_error) && (flags & LOOKUP_DELEGATING_CONS)) check_self_delegation (arg); @@ -9280,8 +9284,14 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE && !is_dummy_object (instance) && TREE_SIDE_EFFECTS (instance)) - call = build2 (COMPOUND_EXPR, TREE_TYPE (call), - instance, call); + { + /* But avoid the implicit lvalue-rvalue conversion when 'a' + is volatile. */ + tree a = instance; + if (TREE_THIS_VOLATILE (a)) + a = build_this (a); + call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call); + } else if (call != error_mark_node && DECL_DESTRUCTOR_P (cand->fn) && !VOID_TYPE_P (TREE_TYPE (call))) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e48a04ade7d..afa5c41bfff 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4216,8 +4216,14 @@ build_base_field_1 (tree t, tree basetype, tree *&next_field) DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; DECL_FIELD_CONTEXT (decl) = t; - DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); - DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); + if (is_empty_class (basetype)) + /* CLASSTYPE_SIZE is one byte, but the field needs to have size zero. */ + DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = size_zero_node; + else + { + DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); + DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); + } SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype)); DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype); SET_DECL_MODE (decl, TYPE_MODE (basetype)); @@ -7122,7 +7128,8 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) case CALL_EXPR: /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) + if (CALL_EXPR_FN (instance) + && TREE_HAS_CONSTRUCTOR (instance)) { if (nonnull) *nonnull = 1; diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index d89bdd5a6a4..47ff90cb055 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1763,7 +1763,13 @@ reduced_constant_expression_p (tree t) /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */ tree idx, val, field; unsigned HOST_WIDE_INT i; if (CONSTRUCTOR_NO_IMPLICIT_ZERO (t)) - field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t))); + { + if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) + /* An initialized vector would have a VECTOR_CST. */ + return false; + else + field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t))); + } else field = NULL_TREE; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val) @@ -4254,7 +4260,16 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, non_constant_p, overflow_p); - *jump_target = t; + if (jump_target) + *jump_target = t; + else + { + /* Can happen with ({ return true; }) && false; passed to + maybe_constant_value. There is nothing to jump over in this + case, and the bug will be diagnosed later. */ + gcc_assert (ctx->quiet); + *non_constant_p = true; + } break; case SAVE_EXPR: @@ -4726,6 +4741,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, jump_target); break; + case USING_STMT: + r = void_node; + break; + default: if (STATEMENT_CODE_P (TREE_CODE (t))) { @@ -5591,6 +5610,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case OMP_PARALLEL: case OMP_TASK: case OMP_FOR: + case OMP_SIMD: case OMP_DISTRIBUTE: case OMP_TASKLOOP: case OMP_TEAMS: diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 622c9fe97a5..37eded17c94 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1918,7 +1918,7 @@ tsubst_constraint_info (tree t, tree args, tree tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl) { - if (t == NULL_TREE) + if (t == NULL_TREE || t == error_mark_node) return t; switch (TREE_CODE (t)) { diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index a45dda4d012..5289a89e486 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -349,6 +349,11 @@ cxx_block_may_fallthru (const_tree stmt) case THROW_EXPR: return false; + case IF_STMT: + if (block_may_fallthru (THEN_CLAUSE (stmt))) + return true; + return block_may_fallthru (ELSE_CLAUSE (stmt)); + case SWITCH_STMT: return (!SWITCH_STMT_ALL_CASES_P (stmt) || !SWITCH_STMT_NO_BREAK_P (stmt) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9a9e9f0bbcb..9038d677b2d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6470,10 +6470,11 @@ extern tree make_auto (void); extern tree make_decltype_auto (void); extern tree make_template_placeholder (tree); extern bool template_placeholder_p (tree); -extern tree do_auto_deduction (tree, tree, tree); extern tree do_auto_deduction (tree, tree, tree, - tsubst_flags_t, - auto_deduction_context, + tsubst_flags_t + = tf_warning_or_error, + auto_deduction_context + = adc_unspecified, tree = NULL_TREE, int = LOOKUP_NORMAL); extern tree type_uses_auto (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3ccea9e6a45..f91f311a117 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4091,8 +4091,14 @@ cxx_init_decl_processing (void) pop_namespace (); flag_noexcept_type = (cxx_dialect >= cxx17); + /* There's no fixed location for <command-line>, the current + location is <builtins>, which is somewhat confusing. */ if (!flag_new_for_scope) - warning (OPT_Wdeprecated, "%<-fno-for-scope%> is deprecated"); + warning_at (UNKNOWN_LOCATION, OPT_Wdeprecated, + "%<-fno-for-scope%> is deprecated"); + if (flag_friend_injection) + warning_at (UNKNOWN_LOCATION, OPT_Wdeprecated, + "%<-ffriend-injection%> is deprecated"); c_common_nodes_and_builtins (); @@ -9834,7 +9840,14 @@ check_special_function_return_type (special_function_kind sfk, error_at (smallest_type_quals_location (type_quals, locations), "qualifiers are not allowed on declaration of " "deduction guide"); - type = make_template_placeholder (CLASSTYPE_TI_TEMPLATE (optype)); + if (TREE_CODE (optype) == TEMPLATE_TEMPLATE_PARM) + { + error ("template template parameter %qT in declaration of " + "deduction guide", optype); + type = error_mark_node; + } + else + type = make_template_placeholder (CLASSTYPE_TI_TEMPLATE (optype)); for (int i = 0; i < ds_last; ++i) if (i != ds_explicit && locations[i]) error_at (locations[i], @@ -12128,7 +12141,7 @@ grokdeclarator (const cp_declarator *declarator, { error ("%qE is neither function nor member function; " "cannot be declared friend", unqualified_id); - friendp = 0; + return error_mark_node; } decl = NULL_TREE; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 2da6f9023c5..d2693ce458b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1825,6 +1825,11 @@ mark_vtable_entries (tree decl) function, so we emit the thunks there instead. */ if (DECL_THUNK_P (fn)) use_thunk (fn, /*emit_p=*/0); + /* Set the location, as marking the function could cause + instantiation. We do not need to preserve the incoming + location, as we're called from c_parse_final_cleanups, which + takes care of that. */ + input_location = DECL_SOURCE_LOCATION (fn); mark_used (fn); } } @@ -4727,6 +4732,9 @@ c_parse_final_cleanups (void) reconsider = true; keyed_classes->unordered_remove (i); } + /* The input_location may have been changed during marking of + vtable entries. */ + input_location = locus_at_end_of_parsing; /* Write out needed type info variables. We have to be careful looping through unemitted decls, because emit_tinfo_decl may diff --git a/gcc/cp/error.c b/gcc/cp/error.c index cb1dcf36201..75e853a1428 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1472,7 +1472,7 @@ find_typenames_r (tree *tp, int *walk_subtrees, void *data) /* Add the typename without any cv-qualifiers. */ mv = TYPE_MAIN_VARIANT (*tp); - if (TREE_CODE (*tp) == TYPE_PACK_EXPANSION) + if (PACK_EXPANSION_P (*tp)) { /* Don't mess with parameter packs since we don't remember the pack expansion context for a particular typename. */ diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 669bf9f6eaf..0b46698b974 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -1217,6 +1217,10 @@ build_noexcept_spec (tree expr, int complain) { gcc_assert (processing_template_decl || TREE_CODE (expr) == DEFERRED_NOEXCEPT); + if (TREE_CODE (expr) != DEFERRED_NOEXCEPT) + /* Avoid problems with a function type built with a dependent typedef + being reused in another scope (c++/84045). */ + expr = strip_typedefs_expr (expr); return build_tree_list (expr, NULL_TREE); } } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 233f41c2592..d0d14abdc9f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3593,7 +3593,7 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts, d_init = (**init)[0]; d_init = resolve_nondeduced_context (d_init, complain); } - type = do_auto_deduction (type, d_init, auto_node); + type = do_auto_deduction (type, d_init, auto_node, complain); } } diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 6b5bd800741..a0a80dfde5c 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -261,6 +261,7 @@ is_capture_proxy (tree decl) return (VAR_P (decl) && DECL_HAS_VALUE_EXPR_P (decl) && !DECL_ANON_UNION_VAR_P (decl) + && !DECL_DECOMPOSITION_P (decl) && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl))); } @@ -450,11 +451,12 @@ build_capture_proxy (tree member, tree init) { if (PACK_EXPANSION_P (init)) init = PACK_EXPANSION_PATTERN (init); - if (INDIRECT_REF_P (init)) - init = TREE_OPERAND (init, 0); - STRIP_NOPS (init); } + if (INDIRECT_REF_P (init)) + init = TREE_OPERAND (init, 0); + STRIP_NOPS (init); + gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL); while (is_normal_capture_proxy (init)) init = DECL_CAPTURED_VARIABLE (init); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e5a34003702..9117e0b30eb 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3071,6 +3071,7 @@ do_pushdecl (tree decl, bool is_friend) old = OVL_CHAIN (old); check_template_shadow (decl); + bool visible_injection = false; if (DECL_DECLARES_FUNCTION_P (decl)) { @@ -3079,14 +3080,20 @@ do_pushdecl (tree decl, bool is_friend) if (is_friend) { if (level->kind != sk_namespace) - /* In a local class, a friend function declaration must - find a matching decl in the innermost non-class scope. - [class.friend/11] */ - error ("friend declaration %qD in local class without " - "prior local declaration", decl); - else if (!flag_friend_injection) + { + /* In a local class, a friend function declaration must + find a matching decl in the innermost non-class scope. + [class.friend/11] */ + error ("friend declaration %qD in local class without " + "prior local declaration", decl); + /* Don't attempt to push it. */ + return error_mark_node; + } + if (!flag_friend_injection) /* Hide it from ordinary lookup. */ DECL_ANTICIPATED (decl) = DECL_HIDDEN_FRIEND_P (decl) = true; + else + visible_injection = true; } } @@ -3138,6 +3145,9 @@ do_pushdecl (tree decl, bool is_friend) } else if (VAR_P (decl)) maybe_register_incomplete_var (decl); + else if (visible_injection) + warning (0, "injected friend %qD is visible" + " due to %<-ffriend-injection%>", decl); if ((VAR_P (decl) || TREE_CODE (decl) == FUNCTION_DECL) && DECL_EXTERN_C_P (decl)) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 81c6f0128e6..4fa546a086c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9331,12 +9331,18 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, && lookahead_prec <= current.prec && sp == stack) { - current.lhs - = build_min (current.tree_type, - TREE_CODE_CLASS (current.tree_type) == tcc_comparison - ? boolean_type_node : TREE_TYPE (current.lhs), - current.lhs.get_value (), rhs.get_value ()); - SET_EXPR_LOCATION (current.lhs, combined_loc); + if (current.lhs == error_mark_node || rhs == error_mark_node) + current.lhs = error_mark_node; + else + { + current.lhs + = build_min (current.tree_type, + TREE_CODE_CLASS (current.tree_type) + == tcc_comparison + ? boolean_type_node : TREE_TYPE (current.lhs), + current.lhs.get_value (), rhs.get_value ()); + SET_EXPR_LOCATION (current.lhs, combined_loc); + } } else { @@ -19644,12 +19650,12 @@ cp_parser_init_declarator (cp_parser* parser, member templates. The former involves deferring parsing of the initializer until end of class as with default arguments. So right here we only handle the latter. */ - if (!member_p && processing_template_decl) + if (!member_p && processing_template_decl && decl != error_mark_node) start_lambda_scope (decl); initializer = cp_parser_initializer (parser, &is_direct_init, &is_non_constant_init); - if (!member_p && processing_template_decl) + if (!member_p && processing_template_decl && decl != error_mark_node) finish_lambda_scope (); if (initializer == error_mark_node) cp_parser_skip_to_end_of_statement (parser); @@ -21919,7 +21925,7 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p) /* Consume the `{' token. */ matching_braces braces; - braces.consume_open (parser); + braces.require_open (parser); /* Create a CONSTRUCTOR to represent the braced-initializer. */ initializer = make_node (CONSTRUCTOR); /* If it's not a `}', then there is a non-trivial initializer. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 222084df4cb..85d1adbbe3c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6143,7 +6143,12 @@ convert_nontype_argument_function (tree type, tree expr, accept: if (TREE_CODE (type) == REFERENCE_TYPE) - fn = build_address (fn); + { + if (REFERENCE_REF_P (fn)) + fn = TREE_OPERAND (fn, 0); + else + fn = build_address (fn); + } if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn))) fn = build_nop (type, fn); @@ -11521,8 +11526,9 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, context. */ tree gen = TREE_PURPOSE (elt); tree inst = TREE_VALUE (elt); - if (DECL_PACK_P (inst)) - inst = retrieve_local_specialization (inst); + if (DECL_P (inst)) + if (tree local = retrieve_local_specialization (inst)) + inst = local; /* else inst is already a full instantiation of the pack. */ register_local_specialization (inst, gen); } @@ -15785,7 +15791,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv, tree auto_node = type_uses_auto (TREE_TYPE (decl)); if (auto_node && init) TREE_TYPE (decl) - = do_auto_deduction (TREE_TYPE (decl), init, auto_node); + = do_auto_deduction (TREE_TYPE (decl), init, auto_node, complain); gcc_assert (!type_dependent_expression_p (decl)); @@ -17064,6 +17070,10 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) bool nested = cfun; if (nested) push_function_context (); + else + /* Still increment function_depth so that we don't GC in the + middle of an expression. */ + ++function_depth; local_specialization_stack s (lss_copy); @@ -17078,6 +17088,8 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (nested) pop_function_context (); + else + --function_depth; /* The capture list was built up in reverse order; fix that now. */ LAMBDA_EXPR_CAPTURE_LIST (r) @@ -23546,6 +23558,7 @@ static tree tsubst_initializer_list (tree t, tree argvec) { tree inits = NULL_TREE; + tree target_ctor = error_mark_node; for (; t; t = TREE_CHAIN (t)) { @@ -23662,6 +23675,28 @@ tsubst_initializer_list (tree t, tree argvec) in_base_initializer = 0; } + if (target_ctor != error_mark_node + && init != error_mark_node) + { + error ("mem-initializer for %qD follows constructor delegation", + decl); + return inits; + } + /* Look for a target constructor. */ + if (init != error_mark_node + && decl && CLASS_TYPE_P (decl) + && same_type_p (decl, current_class_type)) + { + maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS); + if (inits) + { + error ("constructor delegation follows mem-initializer for %qD", + TREE_PURPOSE (inits)); + continue; + } + target_ctor = init; + } + if (decl) { init = build_tree_list (decl, init); @@ -25453,7 +25488,8 @@ dguide_name (tree tmpl) bool dguide_name_p (tree name) { - return (TREE_TYPE (name) + return (TREE_CODE (name) == IDENTIFIER_NODE + && TREE_TYPE (name) && !strncmp (IDENTIFIER_POINTER (name), dguide_base, strlen (dguide_base))); } @@ -25941,17 +25977,6 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, } /* Replace occurrences of 'auto' in TYPE with the appropriate type deduced - from INIT. AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE. */ - -tree -do_auto_deduction (tree type, tree init, tree auto_node) -{ - return do_auto_deduction (type, init, auto_node, - tf_warning_or_error, - adc_unspecified); -} - -/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced from INIT. AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE. The CONTEXT determines the context in which auto deduction is performed and is used to control error diagnostics. FLAGS are the LOOKUP_* flags. @@ -25986,7 +26011,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, /* C++17 class template argument deduction. */ return do_class_deduction (type, tmpl, init, flags, complain); - if (TREE_TYPE (init) == NULL_TREE) + if (init == NULL_TREE || TREE_TYPE (init) == NULL_TREE) /* Nothing we can do with this, even in deduction context. */ return type; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f0cee68e46f..35569d0cb0d 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -731,6 +731,7 @@ finish_if_stmt_cond (tree cond, tree if_stmt) { cond = maybe_convert_cond (cond); if (IF_STMT_CONSTEXPR_P (if_stmt) + && !type_dependent_expression_p (cond) && require_constant_expression (cond) && !value_dependent_expression_p (cond)) { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index a53bddf2ef0..39c1ef28b2d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2896,6 +2896,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data) { u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1), tf_warning_or_error); + if (u == error_mark_node) + return u; if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1))) AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true; } @@ -2913,6 +2915,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data) (splay_tree_value) TREE_OPERAND (u, 0)); TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1)); + if (TREE_OPERAND (u, 1) == error_mark_node) + return error_mark_node; /* Replace the old expression with the new version. */ *tp = u; @@ -3025,7 +3029,8 @@ break_out_target_exprs (tree t) target_remap = splay_tree_new (splay_tree_compare_pointers, /*splay_tree_delete_key_fn=*/NULL, /*splay_tree_delete_value_fn=*/NULL); - cp_walk_tree (&t, bot_manip, target_remap, NULL); + if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node) + t = error_mark_node; cp_walk_tree (&t, bot_replace, target_remap, NULL); if (!--target_remap_count) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index dfcf71689c6..0e7c63dd197 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9232,7 +9232,8 @@ check_return_expr (tree retval, bool *no_warning) /* Effective C++ rule 15. See also start_function. */ if (warn_ecpp - && DECL_NAME (current_function_decl) == assign_op_identifier) + && DECL_NAME (current_function_decl) == assign_op_identifier + && !type_dependent_expression_p (retval)) { bool warn = true; |