diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 330 | ||||
-rw-r--r-- | gcc/cp/call.c | 22 | ||||
-rw-r--r-- | gcc/cp/class.c | 17 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 39 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 51 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 78 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 16 | ||||
-rw-r--r-- | gcc/cp/error.c | 1 | ||||
-rw-r--r-- | gcc/cp/init.c | 1 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 62 | ||||
-rw-r--r-- | gcc/cp/pt.c | 75 | ||||
-rw-r--r-- | gcc/cp/search.c | 2 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 48 | ||||
-rw-r--r-- | gcc/cp/tree.c | 22 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 68 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 9 |
19 files changed, 705 insertions, 144 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 63e0025dbb7..4cc49d77cff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,333 @@ +2018-07-03 Jason Merrill <jason@redhat.com> + + PR c++/86378 - functional cast in noexcept-specifier. + * tree.c (strip_typedefs_expr) [TREE_LIST]: Fix iteration. + +2018-06-26 Jason Merrill <jason@redhat.com> + + PR c++/80290 - memory-hog with std::pair. + * pt.c (type_unification_real): Skip non-dependent conversion + check for a nested list argument. + (braced_init_depth): New. + +2018-06-26 Jakub Jelinek <jakub@redhat.com> + + PR c++/86291 + * parser.c (cp_parser_omp_for_loop_init): Change for_block argument + type from vec<tree, va_gc> * to vec<tree, va_gc> *&. + +2018-06-22 Jakub Jelinek <jakub@redhat.com> + + Backported from mainline + 2018-05-29 Jakub Jelinek <jakub@redhat.com> + + PR c++/85952 + * init.c (build_aggr_init): For structured binding initialized from + array call mark_rvalue_use on the initializer. + + 2018-05-11 Jakub Jelinek <jakub@redhat.com> + + PR c/85696 + * cp-tree.h (cxx_omp_predetermined_sharing_1): New prototype. + * cp-gimplify.c (cxx_omp_predetermined_sharing): New wrapper around + cxx_omp_predetermined_sharing_1. Rename old function to ... + (cxx_omp_predetermined_sharing_1): ... this. + * semantics.c (finish_omp_clauses): Use cxx_omp_predetermined_sharing_1 + instead of cxx_omp_predetermined_sharing. + + 2018-05-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/85662 + * cp-gimplify.c (cp_fold): Use fold_offsetof rather than + fold_offsetof_1, pass TREE_TYPE (x) as TYPE to it and drop the + fold_convert. + + 2018-04-18 Jakub Jelinek <jakub@redhat.com> + + PR c++/84463 + * typeck.c (cp_build_addr_expr_1): Move handling of offsetof-like + tricks from here to ... + * cp-gimplify.c (cp_fold) <case ADDR_EXPR>: ... here. Only use it + if INDIRECT_REF's operand is INTEGER_CST cast to pointer type. + + 2018-04-06 Jakub Jelinek <jakub@redhat.com> + + PR c++/85210 + * pt.c (tsubst_decomp_names): Return error_mark_node and assert + errorcount is set if tsubst doesn't return a VAR_DECL. + + 2018-04-05 Jakub Jelinek <jakub@redhat.com> + + PR c++/85208 + * decl.c (start_decl): For DECL_DECOMPOSITION_P decls, don't call + maybe_apply_pragma_weak here... + (cp_maybe_mangle_decomp): ... but call it here instead. + + 2018-04-04 Jakub Jelinek <jakub@redhat.com> + + PR inline-asm/85172 + * constexpr.c (cxx_eval_builtin_function_call): For calls to + builtin_valid_in_constant_expr_p functions, don't call + cxx_eval_constant_expression if argument is not + potential_constant_expression. + + 2018-04-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/85147 + * pt.c (fixed_parameter_pack_p_1): Punt if parm is error_mark_node. + + PR c++/85140 + * name-lookup.c (handle_namespace_attrs): Return early if attributes + is error_mark_node. + + 2018-03-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/84791 + * semantics.c (finish_omp_reduction_clause): If + OMP_CLAUSE_REDUCTION_PLACEHOLDER is error_mark_node, return true + even if processing_template_decl. + + 2018-03-27 Jakub Jelinek <jakub@redhat.com> + + PR c++/85076 + * tree.c (cp_build_reference_type): If to_type is error_mark_node, + return it right away. + + PR c++/85068 + * class.c (update_vtable_entry_for_fn): Don't ICE if base_binfo + is NULL. Assert if thunk_binfo is NULL then errorcount is non-zero. + + 2018-03-21 Jakub Jelinek <jakub@redhat.com> + + PR c++/84961 + * cp-tree.h (genericize_compound_lvalue): Declare. + * typeck.c (genericize_compound_lvalue): New function. + (unary_complex_lvalue, cp_build_modify_expr): Use it. + * semantics.c (finish_asm_stmt): Replace MODIFY_EXPR, PREINCREMENT_EXPR + and PREDECREMENT_EXPR in output and "m" constrained input operands with + COMPOUND_EXPR. Call cxx_mark_addressable on the rightmost + COMPOUND_EXPR operand. + + 2018-03-16 Jakub Jelinek <jakub@redhat.com> + + PR c++/84874 + * decl.c (reshape_init_class): Don't assert d->cur->index == field + if d->cur->index is a FIELD_DECL, instead set field to d->cur->index. + + 2018-03-15 Jakub Jelinek <jakub@redhat.com> + + PR c++/84222 + * cp-tree.h (cp_warn_deprecated_use): Declare. + * tree.c (cp_warn_deprecated_use): New function. + * typeck2.c (build_functional_cast): Use it. + * decl.c (grokparms): Likewise. + (grokdeclarator): Likewise. Temporarily push nested class scope + around grokparms call for out of class member definitions. + + 2018-03-09 Jason Merrill <jason@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/84076 + * call.c (convert_arg_to_ellipsis): Instead of cp_build_addr_expr + build ADDR_EXPR with REFERENCE_TYPE. + (build_over_call): For purposes of check_function_arguments, if + argarray[j] is ADDR_EXPR with REFERENCE_TYPE created above, use + its operand rather than the argument itself. + + 2018-03-08 Jason Merrill <jason@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/80598 + * call.c (build_over_call): In templates set TREE_USED (first_fn) when + not calling mark_used for the benefit of -Wunused-function warning. + + 2018-03-02 Jakub Jelinek <jakub@redhat.com> + + PR c++/84662 + * pt.c (tsubst_copy_and_build) <case TEMPLATE_ID_EXPR>: Use + RETURN instead of return. + <case POINTER_PLUS_EXPR>: Likewise. + <case CONVERT_EXPR>: If op0 is error_mark_node, just return + it instead of wrapping it into CONVERT_EXPR. + +2018-06-12 Jason Merrill <jason@redhat.com> + + PR c++/85815 - reference to member of enclosing template. + * parser.c (cp_parser_postfix_dot_deref_expression): Check + currently_open_class. + + PR c++/86060 - ICE on range for with -std=c++98. + * parser.c (cp_parser_init_statement): Don't clobber *decl after + pedwarn. + +2018-05-07 Jason Merrill <jason@redhat.com> + + PR c++/85646 - lambda visibility. + * decl2.c (determine_visibility): Don't mess with template arguments + from the containing scope. + (vague_linkage_p): Check DECL_ABSTRACT_P before looking at a 'tor + thunk. + +2018-04-23 Ville Voutilainen <ville.voutilainen@gmail.com> + + Backport from mainline + 2018-04-05 Ville Voutilainen <ville.voutilainen@gmail.com> + + Implement P0969 + * decl.c (find_decomp_class_base): Check accessibility instead + of declared access, adjust diagnostic. + +2018-04-23 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c++/85470 - wrong error with static data member. + * decl.c (check_initializer): Check DECL_INITIALIZED_IN_CLASS_P. + * typeck2.c (store_init_value): Likewise. + +2018-04-23 Ville Voutilainen <ville.voutilainen@gmail.com> + + Backport from mainline + 2018-04-05 Ville Voutilainen <ville.voutilainen@gmail.com> + + Implement P0961 + * decl.c (get_tuple_decomp_init): Check the templatedness + of a member get. + +2018-04-19 Jonathan Wakely <jwakely@redhat.com> + + PR c++/85464 - missing location for -Wignored-qualifiers diagnostic + * decl.c (grokdeclarator): If declspecs->locations[ds_type_spec] + is UNKNOWN_LOCATION fall back to input_location. + +2018-04-09 Jason Merrill <jason@redhat.com> + + PR c++/85279 - dump_expr doesn't understand decltype. + * error.c (dump_expr): Handle DECLTYPE_TYPE. + +2018-04-05 Jason Merrill <jason@redhat.com> + + PR c++/82152 - ICE with class deduction and inherited ctor. + * pt.c (do_class_deduction): Ignore inherited ctors. + + PR c++/84665 - ICE with array of empty class. + * decl2.c (cp_check_const_attributes): Use fold_non_dependent_expr. + + PR c++/85006 - -fconcepts ICE with A<auto...> return type + * pt.c (tsubst_pack_expansion): Allow unsubstituted auto pack. + +2018-04-04 Jason Merrill <jason@redhat.com> + + PR c++/85118 - wrong error with generic lambda and std::bind. + * call.c (add_template_conv_candidate): Disable if there are any + call operators. + + PR c++/85148 - ICE with 'this' in array NSDMI. + * tree.c (replace_placeholders_r): Use handled_component_p. + +2018-04-03 Jason Merrill <jason@redhat.com> + + PR c++/85113 - ICE with constexpr and __builtin_constant_p. + * constexpr.c (cxx_eval_builtin_function_call): Only defer + __builtin_constant_p if ctx->quiet. + + * typeck.c (merge_types): Limit matching attribute shortcut to + the default case. + + PR c++/64095 - auto... parameter pack. + * parser.c (cp_parser_parameter_declaration): Handle turning autos + into packs here. + (cp_parser_parameter_declaration_list): Not here. + + PR c++/85060 - wrong-code with call to base member in template. + * search.c (any_dependent_bases_p): Check uses_template_parms + rather than processing_template_decl. + +2018-03-29 Ville Voutilainen <ville.voutilainen@gmail.com> + + Backport from mainline + 2018-03-23 Ville Voutilainen <ville.voutilainen@gmail.com> + + Implement P0962 + * parser.c (cp_parser_perform_range_for_lookup): Change + the condition for deciding whether to use members. + +2018-03-23 Jason Merrill <jason@redhat.com> + + PR c++/78489 - Substitution in wrong order + PR c++/84489 + * pt.c (type_unification_real): Revert last two changes. + + PR c++/71834 - template-id with too few arguments. + * pt.c (coerce_template_parms): Make sure we gave an error. + + PR c++/84937 - ICE with class deduction and auto. + * pt.c (rewrite_template_parm): Fix auto handling. + + PR c++/80227 - SFINAE and negative array size. + * decl.c (compute_array_index_type): Convert to signed for negative + check. + + PR c++/84839 - ICE with decltype of parameter pack. + * pt.c (tsubst_pack_expansion): Set cp_unevaluated_operand while + instantiating dummy parms. + + PR c++/84798 - ICE with auto in abstract function declarator. + * parser.c (cp_parser_parameter_declaration_clause): Check + parser->default_arg_ok_p. + + PR c++/84355 - ICE with deduction for member class template. + * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Always substitute into + CLASS_PLACEHOLDER_TEMPLATE. + +2018-03-23 Paolo Carlini <paolo.carlini@oracle.com> + Jason Merrill <jason@redhat.com> + + PR c++/82336 - link error with list-init default argument. + * decl.c (check_default_argument): Unshare an initializer list. + +2018-03-22 Marek Polacek <polacek@redhat.com> + + Backported from mainline + 2018-03-22 Marek Polacek <polacek@redhat.com> + + PR c++/84854 + * semantics.c (finish_if_stmt_cond): Check if the type of the condition + is boolean. + + 2018-03-19 Marek Polacek <polacek@redhat.com> + + PR c++/84927 + * constexpr.c (cxx_eval_bare_aggregate): Update constructor's flags + as we evaluate the elements. + (cxx_eval_constant_expression): Verify constructor's flags + unconditionally. + + 2018-03-21 Marek Polacek <polacek@redhat.com> + + PR c++/71638, ICE with NSDMI and reference. + * constexpr.c (cxx_eval_bare_aggregate): Update constructor's flags + even when we replace an element. + +2018-03-09 Jason Merrill <jason@redhat.com> + + PR c++/84785 - ICE with alias template and default targs. + * pt.c (type_unification_real): Set processing_template_decl if + saw_undeduced == 1. + +2018-03-07 Marek Polacek <polacek@redhat.com> + + Backported from mainline + 2018-03-06 Marek Polacek <polacek@redhat.com> + + PR c++/84684 + * constexpr.c (cxx_bind_parameters_in_call): Unshare evaluated + arguments. + +2018-03-03 Jason Merrill <jason@redhat.com> + + PR c++/84686 - missing volatile loads. + * cvt.c (convert_to_void): Call maybe_undo_parenthesized_ref. + 2018-03-03 Jakub Jelinek <jakub@redhat.com> Backported from mainline diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 87729ac01e8..5145e438460 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3259,10 +3259,10 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, tree return_type, tree access_path, tree conversion_path, tsubst_flags_t complain) { - /* Making this work broke PR 71117, so until the committee resolves core - issue 2189, let's disable this candidate if there are any viable call + /* Making this work broke PR 71117 and 85118, so until the committee resolves + core issue 2189, let's disable this candidate if there are any call operators. */ - if (any_strictly_viable (*candidates)) + if (*candidates) return NULL; return @@ -7144,7 +7144,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) "passing objects of non-trivially-copyable " "type %q#T through %<...%> is conditionally supported", arg_type); - return cp_build_addr_expr (arg, complain); + return build1 (ADDR_EXPR, build_reference_type (arg_type), arg); } /* Build up a real lvalue-to-rvalue conversion in case the copy constructor is trivial but not callable. */ @@ -7568,6 +7568,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (undeduced_auto_decl (fn)) mark_used (fn, complain); + else + /* Otherwise set TREE_USED for the benefit of -Wunused-function. + See PR80598. */ + TREE_USED (fn) = 1; return_type = TREE_TYPE (TREE_TYPE (fn)); nargs = vec_safe_length (args); @@ -7931,7 +7935,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) tree *fargs = (!nargs ? argarray : (tree *) alloca (nargs * sizeof (tree))); for (j = 0; j < nargs; j++) - fargs[j] = maybe_constant_value (argarray[j]); + { + /* For -Wformat undo the implicit passing by hidden reference + done by convert_arg_to_ellipsis. */ + if (TREE_CODE (argarray[j]) == ADDR_EXPR + && TREE_CODE (TREE_TYPE (argarray[j])) == REFERENCE_TYPE) + fargs[j] = TREE_OPERAND (argarray[j], 0); + else + fargs[j] = maybe_constant_value (argarray[j]); + } warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn), nargs, fargs); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 5a4c9840acf..a1bf77589dc 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2732,19 +2732,20 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, order. Of course it is lame that we have to repeat the search here anyway -- we should really be caching pieces of the vtable and avoiding this repeated work. */ - tree thunk_binfo, base_binfo; + tree thunk_binfo = NULL_TREE; + tree base_binfo = TYPE_BINFO (base_return); /* Find the base binfo within the overriding function's return type. We will always find a thunk_binfo, except when the covariancy is invalid (which we will have already diagnosed). */ - for (base_binfo = TYPE_BINFO (base_return), - thunk_binfo = TYPE_BINFO (over_return); - thunk_binfo; - thunk_binfo = TREE_CHAIN (thunk_binfo)) - if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo), - BINFO_TYPE (base_binfo))) - break; + if (base_binfo) + for (thunk_binfo = TYPE_BINFO (over_return); thunk_binfo; + thunk_binfo = TREE_CHAIN (thunk_binfo)) + if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo), + BINFO_TYPE (base_binfo))) + break; + gcc_assert (thunk_binfo || errorcount); /* See if virtual inheritance is involved. */ for (virtual_offset = thunk_binfo; diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index a681f89509a..361a955ba01 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1140,7 +1140,10 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, /* Don't fold __builtin_constant_p within a constexpr function. */ bool bi_const_p = (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P); + /* If we aren't requiring a constant expression, defer __builtin_constant_p + in a constexpr function until we have values for the parameters. */ if (bi_const_p + && ctx->quiet && current_function_decl && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) { @@ -1155,8 +1158,14 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, bool dummy1 = false, dummy2 = false; for (i = 0; i < nargs; ++i) { - args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i), - false, &dummy1, &dummy2); + args[i] = CALL_EXPR_ARG (t, i); + /* If builtin_valid_in_constant_expr_p is true, + potential_constant_expression_1 has not recursed into the arguments + of the builtin, verify it here. */ + if (!builtin_valid_in_constant_expr_p (fun) + || potential_constant_expression (args[i])) + args[i] = cxx_eval_constant_expression (&new_ctx, args[i], false, + &dummy1, &dummy2); if (bi_const_p) /* For __built_in_constant_p, fold all expressions with constant values even if they aren't C++ constant-expressions. */ @@ -1274,6 +1283,8 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, if (!*non_constant_p) { + /* Don't share a CONSTRUCTOR that might be changed. */ + arg = unshare_constructor (arg); /* Make sure the binding has the same type as the parm. But only for constant args. */ if (TREE_CODE (type) != REFERENCE_TYPE) @@ -2783,14 +2794,20 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index)))); changed = true; } - else if (new_ctx.ctor != ctx->ctor) + else { - /* We appended this element above; update the value. */ - gcc_assert ((*p)->last().index == index); - (*p)->last().value = elt; + if (new_ctx.ctor != ctx->ctor) + { + /* We appended this element above; update the value. */ + gcc_assert ((*p)->last().index == index); + (*p)->last().value = elt; + } + else + CONSTRUCTOR_APPEND_ELT (*p, index, elt); + /* Adding or replacing an element might change the ctor's flags. */ + TREE_CONSTANT (ctx->ctor) = constant_p; + TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p; } - else - CONSTRUCTOR_APPEND_ELT (*p, index, elt); } if (*non_constant_p || !changed) return t; @@ -4437,11 +4454,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, { /* Don't re-process a constant CONSTRUCTOR, but do fold it to VECTOR_CST if applicable. */ - /* FIXME after GCC 6 branches, make the verify unconditional. */ - if (CHECKING_P) - verify_constructor_flags (t); - else - recompute_constructor_flags (t); + verify_constructor_flags (t); if (TREE_CONSTANT (t)) return fold (t); } diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index b3c6374416a..4891346a609 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1918,7 +1918,7 @@ cxx_omp_const_qual_no_mutable (tree decl) /* True if OpenMP sharing attribute of DECL is predetermined. */ enum omp_clause_default_kind -cxx_omp_predetermined_sharing (tree decl) +cxx_omp_predetermined_sharing_1 (tree decl) { /* Static data members are predetermined shared. */ if (TREE_STATIC (decl)) @@ -1936,6 +1936,32 @@ cxx_omp_predetermined_sharing (tree decl) return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } +/* Likewise, but also include the artificial vars. We don't want to + disallow the artificial vars being mentioned in explicit clauses, + as we use artificial vars e.g. for loop constructs with random + access iterators other than pointers, but during gimplification + we want to treat them as predetermined. */ + +enum omp_clause_default_kind +cxx_omp_predetermined_sharing (tree decl) +{ + enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl); + if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED) + return ret; + + /* Predetermine artificial variables holding integral values, those + are usually result of gimplify_one_sizepos or SAVE_EXPR + gimplification. */ + if (VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && INTEGRAL_TYPE_P (TREE_TYPE (decl)) + && !(DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl))) + return OMP_CLAUSE_DEFAULT_SHARED; + + return OMP_CLAUSE_DEFAULT_UNSPECIFIED; +} + /* Finalize an implicitly determined clause. */ void @@ -2156,6 +2182,28 @@ cp_fold (tree x) goto unary; case ADDR_EXPR: + loc = EXPR_LOCATION (x); + op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false); + + /* Cope with user tricks that amount to offsetof. */ + if (op0 != error_mark_node + && TREE_CODE (TREE_TYPE (op0)) != FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (op0)) != METHOD_TYPE) + { + tree val = get_base_address (op0); + if (val + && INDIRECT_REF_P (val) + && COMPLETE_TYPE_P (TREE_TYPE (val)) + && TREE_CONSTANT (TREE_OPERAND (val, 0))) + { + val = TREE_OPERAND (val, 0); + STRIP_NOPS (val); + if (TREE_CODE (val) == INTEGER_CST) + return fold_offsetof (op0, TREE_TYPE (x)); + } + } + goto finish_unary; + case REALPART_EXPR: case IMAGPART_EXPR: rval_ops = false; @@ -2173,6 +2221,7 @@ cp_fold (tree x) loc = EXPR_LOCATION (x); op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops); + finish_unary: if (op0 != TREE_OPERAND (x, 0)) { if (op0 == error_mark_node) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fadf6ecb1a2..664def60405 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6708,6 +6708,7 @@ extern tree cxx_copy_lang_qualifiers (const_tree, const_tree); extern void cxx_print_statistics (void); extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t); +extern void cp_warn_deprecated_use (tree); /* in ptree.c */ extern void cxx_print_xnode (FILE *, tree, int); @@ -6777,6 +6778,7 @@ extern tree cp_build_addressof (location_t, tree, extern tree cp_build_addr_expr (tree, tsubst_flags_t); extern tree cp_build_unary_op (enum tree_code, tree, bool, tsubst_flags_t); +extern tree genericize_compound_lvalue (tree); extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (location_t, tree, tree, tree, tsubst_flags_t); @@ -6941,6 +6943,7 @@ extern int cp_gimplify_expr (tree *, gimple_seq *, gimple_seq *); extern void cp_genericize (tree); extern bool cxx_omp_const_qual_no_mutable (tree); +extern enum omp_clause_default_kind cxx_omp_predetermined_sharing_1 (tree); extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree); extern tree cxx_omp_clause_default_ctor (tree, tree, tree); extern tree cxx_omp_clause_copy_ctor (tree, tree, tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 5f4b5e30a5f..5d3a47ec640 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1053,6 +1053,8 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) || TREE_TYPE (expr) == error_mark_node) return error_mark_node; + expr = maybe_undo_parenthesized_ref (expr); + if (implicit == ICV_CAST) mark_exp_read (expr); else diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 730a6f1be37..950e04a6680 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5022,7 +5022,7 @@ start_decl (const cp_declarator *declarator, } /* If #pragma weak was used, mark the decl weak now. */ - if (!processing_template_decl) + if (!processing_template_decl && !DECL_DECOMPOSITION_P (decl)) maybe_apply_pragma_weak (decl); if (TREE_CODE (decl) == FUNCTION_DECL @@ -5796,8 +5796,18 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, return error_mark_node; if (TREE_CODE (d->cur->index) == FIELD_DECL) - /* We already reshaped this. */ - gcc_assert (d->cur->index == field); + { + /* We already reshaped this. */ + if (field != d->cur->index) + { + tree id = DECL_NAME (d->cur->index); + gcc_assert (id); + gcc_checking_assert (lookup_field_1 (type, id, + /*want_type=*/false) + == d->cur->index); + field = d->cur->index; + } + } else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE) field = lookup_field_1 (type, d->cur->index, /*want_type=*/false); else @@ -6400,7 +6410,9 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) } if (init_code - && (DECL_IN_AGGR_P (decl) && !DECL_VAR_DECLARED_INLINE_P (decl))) + && (DECL_IN_AGGR_P (decl) + && DECL_INITIALIZED_IN_CLASS_P (decl) + && !DECL_VAR_DECLARED_INLINE_P (decl))) { static int explained = 0; @@ -7228,9 +7240,9 @@ find_decomp_class_base (location_t loc, tree type, tree ret) inform (DECL_SOURCE_LOCATION (field), "declared here"); return error_mark_node; } - else if (TREE_PRIVATE (field) || TREE_PROTECTED (field)) + else if (!accessible_p (type, field, true)) { - error_at (loc, "cannot decompose non-public member %qD of %qT", + error_at (loc, "cannot decompose inaccessible member %qD of %qT", field, type); inform (DECL_SOURCE_LOCATION (field), TREE_PRIVATE (field) @@ -7338,7 +7350,29 @@ get_tuple_decomp_init (tree decl, unsigned i) tree fns = lookup_qualified_name (TREE_TYPE (e), get_id, /*type*/false, /*complain*/false); - if (fns != error_mark_node) + bool use_member_get = false; + + /* To use a member get, member lookup must find at least one + declaration that is a function template + whose first template parameter is a non-type parameter. */ + for (tree iter = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns; + iter; + iter = OVL_NEXT (iter)) + { + tree fn = OVL_CURRENT (iter); + if (TREE_CODE (fn) == TEMPLATE_DECL) + { + tree tparms = DECL_TEMPLATE_PARMS (fn); + tree parm = TREE_VEC_ELT (INNERMOST_TEMPLATE_PARMS (tparms), 0); + if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL) + { + use_member_get = true; + break; + } + } + } + + if (use_member_get) { fns = lookup_template_function (fns, targs); return build_new_method_call (e, fns, /*args*/NULL, @@ -7388,6 +7422,7 @@ cp_maybe_mangle_decomp (tree decl, tree first, unsigned int count) for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) v[count - i - 1] = d; SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v)); + maybe_apply_pragma_weak (decl); } } @@ -9524,7 +9559,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) constant_expression_error (size); /* An array must have a positive number of elements. */ - if (tree_int_cst_lt (size, integer_zero_node)) + tree signed_size = fold_convert (ssizetype, size); + if (tree_int_cst_lt (signed_size, integer_zero_node)) { if (!(complain & tf_error)) return error_mark_node; @@ -10104,6 +10140,8 @@ grokdeclarator (const cp_declarator *declarator, declspecs->locations); if (typespec_loc == UNKNOWN_LOCATION) typespec_loc = declspecs->locations[ds_type_spec]; + if (typespec_loc == UNKNOWN_LOCATION) + typespec_loc = input_location; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ @@ -10373,7 +10411,7 @@ grokdeclarator (const cp_declarator *declarator, suppress reports of deprecated items. */ if (type && TREE_DEPRECATED (type) && deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (type, NULL_TREE); + cp_warn_deprecated_use (type); if (type && TREE_CODE (type) == TYPE_DECL) { typedef_decl = type; @@ -10381,7 +10419,7 @@ grokdeclarator (const cp_declarator *declarator, if (TREE_DEPRECATED (type) && DECL_ARTIFICIAL (typedef_decl) && deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (type, NULL_TREE); + cp_warn_deprecated_use (type); } /* No type at all: default to `int', and set DEFAULTED_INT because it was not a user-defined typedef. */ @@ -11176,8 +11214,18 @@ grokdeclarator (const cp_declarator *declarator, explicitp = 2; } - arg_types = grokparms (declarator->u.function.parameters, - &parms); + tree pushed_scope = NULL_TREE; + if (funcdecl_p + && decl_context != FIELD + && inner_declarator->u.id.qualifying_scope + && CLASS_TYPE_P (inner_declarator->u.id.qualifying_scope)) + pushed_scope + = push_scope (inner_declarator->u.id.qualifying_scope); + + arg_types = grokparms (declarator->u.function.parameters, &parms); + + if (pushed_scope) + pop_scope (pushed_scope); if (inner_declarator && inner_declarator->kind == cdk_id @@ -12563,7 +12611,9 @@ check_default_argument (tree decl, tree arg, tsubst_flags_t complain) A default argument expression is implicitly converted to the parameter type. */ ++cp_unevaluated_operand; - perform_implicit_conversion_flags (decl_type, arg, complain, + /* Avoid digest_init clobbering the initializer. */ + tree carg = BRACE_ENCLOSED_INITIALIZER_P (arg) ? unshare_expr (arg): arg; + perform_implicit_conversion_flags (decl_type, carg, complain, LOOKUP_IMPLICIT); --cp_unevaluated_operand; @@ -12692,7 +12742,7 @@ grokparms (tree parmlist, tree *parms) { tree deptype = type_is_deprecated (type); if (deptype) - warn_deprecated_use (deptype, NULL_TREE); + cp_warn_deprecated_use (deptype); } /* Top-level qualifiers on the parameters are diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b1c3c30521f..7ad6a108224 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1360,7 +1360,7 @@ cp_check_const_attributes (tree attributes) { tree expr = TREE_VALUE (arg); if (EXPR_P (expr)) - TREE_VALUE (arg) = maybe_constant_value (expr); + TREE_VALUE (arg) = fold_non_dependent_expr (expr); } } } @@ -1829,10 +1829,13 @@ vague_linkage_p (tree decl) { if (!TREE_PUBLIC (decl)) { - /* maybe_thunk_body clears TREE_PUBLIC on the maybe-in-charge 'tor - variants, check one of the "clones" for the real linkage. */ + /* maybe_thunk_body clears TREE_PUBLIC and DECL_ABSTRACT_P on the + maybe-in-charge 'tor variants; in that case we need to check one of + the "clones" for the real linkage. But only in that case; before + maybe_clone_body we haven't yet copied the linkage to the clones. */ if ((DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl) || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)) + && !DECL_ABSTRACT_P (decl) && DECL_CHAIN (decl) && DECL_CLONED_FUNCTION (DECL_CHAIN (decl))) return vague_linkage_p (DECL_CHAIN (decl)); @@ -2310,11 +2313,8 @@ determine_visibility (tree decl) } /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set, - but have no TEMPLATE_INFO. Their containing template - function does, and the local class could be constrained - by that. */ - if (template_decl) - template_decl = fn; + but have no TEMPLATE_INFO, so don't try to check it. */ + template_decl = NULL_TREE; } else if (VAR_P (decl) && DECL_TINFO_P (decl) && flag_visibility_ms_compat) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 38bc0b2474a..989a5e8eda1 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2695,6 +2695,7 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) case INTEGER_TYPE: case COMPLEX_TYPE: case VECTOR_TYPE: + case DECLTYPE_TYPE: pp_type_specifier_seq (pp, t); break; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e9c39ff25e6..ec01f6b6776 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1632,6 +1632,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp)) { from_array = 1; + init = mark_rvalue_use (init); if (init && DECL_P (init) && !(flags & LOOKUP_ONLYCONVERTING)) { diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index dc8e82c2fe2..6ccfdbfdb71 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3684,6 +3684,9 @@ handle_namespace_attrs (tree ns, tree attributes) tree d; bool saw_vis = false; + if (attributes == error_mark_node) + return false; + for (d = attributes; d; d = TREE_CHAIN (d)) { tree name = get_attribute_name (d); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ede8ca8097c..24ecf17b3b4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7364,9 +7364,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, if (postfix_expression != current_class_ref && scope != error_mark_node && !(processing_template_decl - && current_class_type - && (same_type_ignoring_top_level_qualifiers_p - (scope, current_class_type)))) + && currently_open_class (scope))) { scope = complete_type (scope); if (!COMPLETE_TYPE_P (scope) @@ -11858,7 +11856,7 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end) /*protect=*/2, /*want_type=*/false, tf_warning_or_error); - if (member_begin != NULL_TREE || member_end != NULL_TREE) + if (member_begin != NULL_TREE && member_end != NULL_TREE) { /* Use the member functions. */ if (member_begin != NULL_TREE) @@ -12103,12 +12101,9 @@ cp_parser_init_statement (cp_parser* parser, tree *decl) cp_lexer_consume_token (parser->lexer); is_range_for = true; if (cxx_dialect < cxx11) - { - pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0, - "range-based %<for%> loops only available with " - "-std=c++11 or -std=gnu++11"); - *decl = error_mark_node; - } + pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0, + "range-based %<for%> loops only available with " + "-std=c++11 or -std=gnu++11"); } else /* The ';' is not consumed yet because we told @@ -20969,7 +20964,10 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) if (!processing_specialization && !processing_template_parmlist - && !processing_explicit_instantiation) + && !processing_explicit_instantiation + /* default_arg_ok_p tracks whether this is a parameter-clause for an + actual function or a random abstract declarator. */ + && parser->default_arg_ok_p) if (!current_function_decl || (current_class_type && LAMBDA_TYPE_P (current_class_type))) parser->auto_is_implicit_function_template_parm_p = true; @@ -21078,9 +21076,6 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) cp_parameter_declarator *parameter; tree decl = error_mark_node; bool parenthesized_p = false; - int template_parm_idx = (function_being_declared_is_template_p (parser)? - TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS - (current_template_parms)) : 0); /* Parse the parameter. */ parameter @@ -21094,22 +21089,6 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) if (parameter) { - /* If a function parameter pack was specified and an implicit template - parameter was introduced during cp_parser_parameter_declaration, - change any implicit parameters introduced into packs. */ - if (parser->implicit_template_parms - && parameter->declarator - && parameter->declarator->parameter_pack_p) - { - int latest_template_parm_idx = TREE_VEC_LENGTH - (INNERMOST_TEMPLATE_PARMS (current_template_parms)); - - if (latest_template_parm_idx != template_parm_idx) - parameter->decl_specifiers.type = convert_generic_types_to_packs - (parameter->decl_specifiers.type, - template_parm_idx, latest_template_parm_idx); - } - decl = grokdeclarator (parameter->declarator, ¶meter->decl_specifiers, PARM, @@ -21267,6 +21246,10 @@ cp_parser_parameter_declaration (cp_parser *parser, parser->type_definition_forbidden_message = G_("types may not be defined in parameter types"); + int template_parm_idx = (function_being_declared_is_template_p (parser) ? + TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS + (current_template_parms)) : 0); + /* Parse the declaration-specifiers. */ cp_parser_decl_specifier_seq (parser, CP_PARSER_FLAGS_NONE, @@ -21355,6 +21338,23 @@ cp_parser_parameter_declaration (cp_parser *parser, parameter pack expansion expression. Otherwise, leave the ellipsis for a C-style variadic function. */ token = cp_lexer_peek_token (parser->lexer); + + /* If a function parameter pack was specified and an implicit template + parameter was introduced during cp_parser_parameter_declaration, + change any implicit parameters introduced into packs. */ + if (parser->implicit_template_parms + && (token->type == CPP_ELLIPSIS + || (declarator && declarator->parameter_pack_p))) + { + int latest_template_parm_idx = TREE_VEC_LENGTH + (INNERMOST_TEMPLATE_PARMS (current_template_parms)); + + if (latest_template_parm_idx != template_parm_idx) + decl_specifiers.type = convert_generic_types_to_packs + (decl_specifiers.type, + template_parm_idx, latest_template_parm_idx); + } + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { tree type = decl_specifiers.type; @@ -34286,7 +34286,7 @@ static tree cp_parser_omp_for_loop_init (cp_parser *parser, enum tree_code code, tree &this_pre_body, - vec<tree, va_gc> *for_block, + vec<tree, va_gc> *&for_block, tree &init, tree &orig_init, tree &decl, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9815df63c28..71077a3b049 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4864,7 +4864,7 @@ static void fixed_parameter_pack_p_1 (tree parm, struct find_parameter_pack_data *ppd) { /* A type parm can't refer to another parm. */ - if (TREE_CODE (parm) == TYPE_DECL) + if (TREE_CODE (parm) == TYPE_DECL || parm == error_mark_node) return; else if (TREE_CODE (parm) == PARM_DECL) { @@ -8265,7 +8265,11 @@ coerce_template_parms (tree parms, } if (lost) - return error_mark_node; + { + if ((complain & tf_error) && !seen_error()) + error ("wrong number of template arguments"); + return error_mark_node; + } if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args)) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, @@ -11475,7 +11479,9 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, { /* This parameter pack was used in an unevaluated context. Just make a dummy decl, since it's only used for its type. */ + ++cp_unevaluated_operand; arg_pack = tsubst_decl (parm_pack, args, complain); + --cp_unevaluated_operand; if (arg_pack && DECL_PACK_P (arg_pack)) /* Partial instantiation of the parm_pack, we can't build up an argument pack yet. */ @@ -11545,7 +11551,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* We can't substitute for this parameter pack. We use a flag as well as the missing_level counter because function parameter packs don't have a level. */ - gcc_assert (processing_template_decl); + gcc_assert (processing_template_decl || is_auto (parm_pack)); unsubstituted_packs = true; } } @@ -13776,8 +13782,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) = tsubst_constraint (constr, args, complain, in_decl); else if (tree pl = CLASS_PLACEHOLDER_TEMPLATE (t)) { - if (DECL_TEMPLATE_TEMPLATE_PARM_P (pl)) - pl = tsubst (pl, args, complain, in_decl); + pl = tsubst_copy (pl, args, complain, in_decl); CLASS_PLACEHOLDER_TEMPLATE (r) = pl; } } @@ -15799,6 +15804,12 @@ tsubst_decomp_names (tree decl, tree pattern_decl, tree args, DECL_HAS_VALUE_EXPR_P (decl2) = 1; if (VAR_P (decl3)) DECL_TEMPLATE_INSTANTIATED (decl3) = 1; + else + { + gcc_assert (errorcount); + decl = error_mark_node; + continue; + } maybe_push_decl (decl3); if (error_operand_p (decl3)) decl = error_mark_node; @@ -16787,14 +16798,14 @@ tsubst_copy_and_build (tree t, if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); if (targs == error_mark_node) - return error_mark_node; + RETURN (error_mark_node); if (TREE_CODE (templ) == SCOPE_REF) { tree name = TREE_OPERAND (templ, 1); tree tid = lookup_template_function (name, targs); TREE_OPERAND (templ, 1) = tid; - return templ; + RETURN (templ); } if (variable_template_p (templ)) @@ -16859,6 +16870,8 @@ tsubst_copy_and_build (tree t, { tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); tree op0 = RECUR (TREE_OPERAND (t, 0)); + if (op0 == error_mark_node) + RETURN (error_mark_node); RETURN (build1 (CONVERT_EXPR, type, op0)); } @@ -17006,7 +17019,7 @@ tsubst_copy_and_build (tree t, { tree op0 = RECUR (TREE_OPERAND (t, 0)); tree op1 = RECUR (TREE_OPERAND (t, 1)); - return fold_build_pointer_plus (op0, op1); + RETURN (fold_build_pointer_plus (op0, op1)); } case SCOPE_REF: @@ -19229,6 +19242,24 @@ try_array_deduction (tree tparms, tree targs, tree parm) /*nondeduced*/false, array_deduction_r); } +/* Returns how many levels of { } INIT contains. */ + +static int +braced_init_depth (tree init) +{ + if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init)) + return 0; + unsigned i; tree val; + unsigned max = 0; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, val) + { + unsigned elt_d = braced_init_depth (val); + if (elt_d > max) + max = elt_d; + } + return max + 1; +} + /* Most parms like fn_type_unification. If SUBR is 1, we're being called recursively (to unify the @@ -19465,6 +19496,10 @@ type_unification_real (tree tparms, if (uses_template_parms (parm)) continue; + /* Workaround for c++/80290: avoid combinatorial explosion on + deeply nested braced init-lists. */ + if (braced_init_depth (arg) > 2) + continue; if (check_non_deducible_conversion (parm, arg, strict, flags, explain_p)) return 1; @@ -19491,10 +19526,10 @@ type_unification_real (tree tparms, if (DECL_P (parm)) input_location = DECL_SOURCE_LOCATION (parm); arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE); - if (arg != error_mark_node && !uses_template_parms (arg)) + if (!uses_template_parms (arg)) arg = convert_template_argument (parm, arg, full_targs, complain, i, NULL_TREE); - else if (saw_undeduced == 1) + else if (saw_undeduced < 2) arg = NULL_TREE; else arg = error_mark_node; @@ -25130,8 +25165,21 @@ rewrite_template_parm (tree olddecl, unsigned index, unsigned level, = TEMPLATE_TYPE_PARM_FOR_CLASS (oldtype); } else - newtype = tsubst (TREE_TYPE (olddecl), tsubst_args, - complain, NULL_TREE); + { + newtype = TREE_TYPE (olddecl); + if (type_uses_auto (newtype)) + { + // Substitute once to fix references to other template parameters. + newtype = tsubst (newtype, tsubst_args, + complain|tf_partial, NULL_TREE); + // Now substitute again to reduce the level of the auto. + newtype = tsubst (newtype, current_template_args (), + complain, NULL_TREE); + } + else + newtype = tsubst (newtype, tsubst_args, + complain, NULL_TREE); + } tree newdecl = build_decl (DECL_SOURCE_LOCATION (olddecl), TREE_CODE (olddecl), @@ -25411,6 +25459,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, // FIXME cache artificial deduction guides for (tree fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) { + if (TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)) + continue; + tree fn = OVL_CURRENT (fns); tree guide = build_deduction_guide (fn, outer_args, complain); cands = ovl_cons (guide, cands); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index f9d770ad8ee..e72ce5a427c 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2879,7 +2879,7 @@ original_binfo (tree binfo, tree here) bool any_dependent_bases_p (tree type) { - if (!type || !CLASS_TYPE_P (type) || !processing_template_decl) + if (!type || !CLASS_TYPE_P (type) || !uses_template_parms (type)) return false; unsigned i; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e0663764638..34ca72e10a0 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -730,7 +730,10 @@ finish_if_stmt_cond (tree cond, tree if_stmt) cond = maybe_convert_cond (cond); if (IF_STMT_CONSTEXPR_P (if_stmt) && require_potential_rvalue_constant_expression (cond) - && !value_dependent_expression_p (cond)) + && !value_dependent_expression_p (cond) + /* Wait until instantiation time, since only then COND has been + converted to bool. */ + && TREE_TYPE (cond) == boolean_type_node) { cond = instantiate_non_dependent_expr (cond); cond = cxx_constant_value (cond, NULL_TREE); @@ -1480,6 +1483,21 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand))))) cxx_readonly_error (operand, lv_asm); + tree *op = &operand; + while (TREE_CODE (*op) == COMPOUND_EXPR) + op = &TREE_OPERAND (*op, 1); + switch (TREE_CODE (*op)) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case MODIFY_EXPR: + *op = genericize_compound_lvalue (*op); + op = &TREE_OPERAND (*op, 1); + break; + default: + break; + } + constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); oconstraints[i] = constraint; @@ -1488,7 +1506,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, { /* If the operand is going to end up in memory, mark it addressable. */ - if (!allows_reg && !cxx_mark_addressable (operand)) + if (!allows_reg && !cxx_mark_addressable (*op)) operand = error_mark_node; } else @@ -1530,7 +1548,23 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, /* Strip the nops as we allow this case. FIXME, this really should be rejected or made deprecated. */ STRIP_NOPS (operand); - if (!cxx_mark_addressable (operand)) + + tree *op = &operand; + while (TREE_CODE (*op) == COMPOUND_EXPR) + op = &TREE_OPERAND (*op, 1); + switch (TREE_CODE (*op)) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case MODIFY_EXPR: + *op = genericize_compound_lvalue (*op); + op = &TREE_OPERAND (*op, 1); + break; + default: + break; + } + + if (!cxx_mark_addressable (*op)) operand = error_mark_node; } else if (!allows_reg && !allows_mem) @@ -5604,7 +5638,11 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) return false; } else if (processing_template_decl) - return false; + { + if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node) + return true; + return false; + } tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c); @@ -7333,7 +7371,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) share_name = "threadprivate"; - else switch (cxx_omp_predetermined_sharing (t)) + else switch (cxx_omp_predetermined_sharing_1 (t)) { case OMP_CLAUSE_DEFAULT_UNSPECIFIED: break; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 65277584aa2..f24e272b0fd 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1050,6 +1050,9 @@ cp_build_reference_type (tree to_type, bool rval) { tree lvalue_ref, t; + if (to_type == error_mark_node) + return error_mark_node; + if (TREE_CODE (to_type) == REFERENCE_TYPE) { rval = rval && TYPE_REF_IS_RVALUE (to_type); @@ -1667,9 +1670,9 @@ strip_typedefs_expr (tree t, bool *remove_attributes) tree it; for (it = t; it; it = TREE_CHAIN (it)) { - tree val = strip_typedefs_expr (TREE_VALUE (t), remove_attributes); + tree val = strip_typedefs_expr (TREE_VALUE (it), remove_attributes); vec_safe_push (vec, val); - if (val != TREE_VALUE (t)) + if (val != TREE_VALUE (it)) changed = true; gcc_assert (TREE_PURPOSE (it) == NULL_TREE); } @@ -2798,7 +2801,7 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_) for (; !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (*t), TREE_TYPE (x)); x = TREE_OPERAND (x, 0)) - gcc_assert (TREE_CODE (x) == COMPONENT_REF); + gcc_assert (handled_component_p (x)); *t = x; *walk_subtrees = false; d->seen = true; @@ -4900,6 +4903,19 @@ cp_tree_code_length (enum tree_code code) } } +/* Wrapper around warn_deprecated_use that doesn't warn for + current_class_type. */ + +void +cp_warn_deprecated_use (tree node) +{ + if (TYPE_P (node) + && current_class_type + && TYPE_MAIN_VARIANT (node) == current_class_type) + return; + warn_deprecated_use (node, NULL_TREE); +} + /* Implement -Wzero_as_null_pointer_constant. Return true if the conditions for the warning hold, false otherwise. */ bool diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d79b724ecca..0da2da1c30f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -905,14 +905,14 @@ merge_types (tree t1, tree t2) return t1; default:; + if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes)) + return t1; + else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes)) + return t2; + break; } - if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes)) - return t1; - else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes)) - return t2; - else - return cp_build_type_attribute_variant (t1, attributes); + return cp_build_type_attribute_variant (t1, attributes); } /* Return the ARRAY_TYPE type without its domain. */ @@ -5713,19 +5713,6 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) return arg; } - /* ??? Cope with user tricks that amount to offsetof. */ - if (TREE_CODE (argtype) != FUNCTION_TYPE - && TREE_CODE (argtype) != METHOD_TYPE - && argtype != unknown_type_node - && (val = get_base_address (arg)) - && COMPLETE_TYPE_P (TREE_TYPE (val)) - && INDIRECT_REF_P (val) - && TREE_CONSTANT (TREE_OPERAND (val, 0))) - { - tree type = build_pointer_type (argtype); - return fold_convert (type, fold_offsetof_1 (arg)); - } - /* Handle complex lvalues (when permitted) by reduction to simpler cases. */ val = unary_complex_lvalue (ADDR_EXPR, arg); @@ -6177,6 +6164,25 @@ build_unary_op (location_t /*location*/, return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error); } +/* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR, + so that it is a valid lvalue even for GENERIC by replacing + (lhs = rhs) with ((lhs = rhs), lhs) + (--lhs) with ((--lhs), lhs) + (++lhs) with ((++lhs), lhs) + and if lhs has side-effects, calling cp_stabilize_reference on it, so + that it can be evaluated multiple times. */ + +tree +genericize_compound_lvalue (tree lvalue) +{ + if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0))) + lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue), + cp_stabilize_reference (TREE_OPERAND (lvalue, 0)), + TREE_OPERAND (lvalue, 1)); + return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)), + lvalue, TREE_OPERAND (lvalue, 0)); +} + /* Apply unary lvalue-demanding operator CODE to the expression ARG for certain kinds of expressions which are not really lvalues but which we can accept as lvalues. @@ -6211,17 +6217,7 @@ unary_complex_lvalue (enum tree_code code, tree arg) if (TREE_CODE (arg) == MODIFY_EXPR || TREE_CODE (arg) == PREINCREMENT_EXPR || TREE_CODE (arg) == PREDECREMENT_EXPR) - { - tree lvalue = TREE_OPERAND (arg, 0); - if (TREE_SIDE_EFFECTS (lvalue)) - { - lvalue = cp_stabilize_reference (lvalue); - arg = build2 (TREE_CODE (arg), TREE_TYPE (arg), - lvalue, TREE_OPERAND (arg, 1)); - } - return unary_complex_lvalue - (code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue)); - } + return unary_complex_lvalue (code, genericize_compound_lvalue (arg)); if (code != ADDR_EXPR) return NULL_TREE; @@ -7617,11 +7613,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, case PREINCREMENT_EXPR: if (compound_side_effects_p) newrhs = rhs = stabilize_expr (rhs, &preeval); - if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) - lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs), - cp_stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); - lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0)); + lhs = genericize_compound_lvalue (lhs); maybe_add_compound: /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5; and looked through the COMPOUND_EXPRs, readd them now around @@ -7644,11 +7636,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, case MODIFY_EXPR: if (compound_side_effects_p) newrhs = rhs = stabilize_expr (rhs, &preeval); - if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) - lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs), - cp_stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); - lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0)); + lhs = genericize_compound_lvalue (lhs); goto maybe_add_compound; case MIN_EXPR: diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 1f0eb454754..c8b9d787ac5 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -817,9 +817,12 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags) bool const_init; value = instantiate_non_dependent_expr (value); if (DECL_DECLARED_CONSTEXPR_P (decl) - || (DECL_IN_AGGR_P (decl) && !DECL_VAR_DECLARED_INLINE_P (decl))) + || (DECL_IN_AGGR_P (decl) + && DECL_INITIALIZED_IN_CLASS_P (decl) + && !DECL_VAR_DECLARED_INLINE_P (decl))) { - /* Diagnose a non-constant initializer for constexpr. */ + /* Diagnose a non-constant initializer for constexpr variable or + non-inline in-class-initialized static data member. */ if (processing_template_decl && !require_potential_constant_expression (value)) value = error_mark_node; @@ -1954,7 +1957,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) if (complain & tf_warning && TREE_DEPRECATED (type) && DECL_ARTIFICIAL (exp)) - warn_deprecated_use (type, NULL_TREE); + cp_warn_deprecated_use (type); } else type = exp; |