diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 150 | ||||
-rw-r--r-- | gcc/cp/call.c | 16 | ||||
-rw-r--r-- | gcc/cp/class.c | 17 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 10 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 51 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/decl.c | 37 | ||||
-rw-r--r-- | gcc/cp/init.c | 1 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 15 | ||||
-rw-r--r-- | gcc/cp/pt.c | 16 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 43 | ||||
-rw-r--r-- | gcc/cp/tree.c | 16 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 56 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 2 |
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; |