aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog150
-rw-r--r--gcc/cp/call.c16
-rw-r--r--gcc/cp/class.c17
-rw-r--r--gcc/cp/constexpr.c10
-rw-r--r--gcc/cp/cp-gimplify.c51
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c37
-rw-r--r--gcc/cp/init.c1
-rw-r--r--gcc/cp/name-lookup.c3
-rw-r--r--gcc/cp/parser.c15
-rw-r--r--gcc/cp/pt.c16
-rw-r--r--gcc/cp/semantics.c43
-rw-r--r--gcc/cp/tree.c16
-rw-r--r--gcc/cp/typeck.c56
-rw-r--r--gcc/cp/typeck2.c2
15 files changed, 362 insertions, 74 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2a5f0e0985e..7fabfa0109b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,153 @@
+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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 012134fd47a..5145e438460 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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 96f8277bdf2..361a955ba01 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1158,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. */
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/decl.c b/gcc/cp/decl.c
index 836506ef7be..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
@@ -7412,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);
}
}
@@ -10400,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;
@@ -10408,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. */
@@ -11203,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
@@ -12721,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/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 9a65d945232..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)
@@ -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
@@ -34291,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 9a1e632fb22..79cfd012922 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)
{
@@ -15804,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;
@@ -16792,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))
@@ -16864,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));
}
@@ -17011,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:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 481c88b0728..34ca72e10a0 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1483,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;
@@ -1491,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
@@ -1533,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)
@@ -5607,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);
@@ -7336,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 5fef52674f6..3b25ab92a15 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);
@@ -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 9d7c9aa27d0..0da2da1c30f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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 764fbca832d..c8b9d787ac5 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1957,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;