aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog330
-rw-r--r--gcc/cp/call.c22
-rw-r--r--gcc/cp/class.c17
-rw-r--r--gcc/cp/constexpr.c39
-rw-r--r--gcc/cp/cp-gimplify.c51
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/cvt.c2
-rw-r--r--gcc/cp/decl.c78
-rw-r--r--gcc/cp/decl2.c16
-rw-r--r--gcc/cp/error.c1
-rw-r--r--gcc/cp/init.c1
-rw-r--r--gcc/cp/name-lookup.c3
-rw-r--r--gcc/cp/parser.c62
-rw-r--r--gcc/cp/pt.c75
-rw-r--r--gcc/cp/search.c2
-rw-r--r--gcc/cp/semantics.c48
-rw-r--r--gcc/cp/tree.c22
-rw-r--r--gcc/cp/typeck.c68
-rw-r--r--gcc/cp/typeck2.c9
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,
&parameter->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;