diff options
author | Gaius Mulley <gaius.mulley@southwales.ac.uk> | 2022-05-03 12:12:33 +0100 |
---|---|---|
committer | Gaius Mulley <gaius.mulley@southwales.ac.uk> | 2022-05-03 12:12:33 +0100 |
commit | b8c70285c3bb19aea0a7bfc0285271b2b1c0bbdd (patch) | |
tree | 19d7f5a784a3bafc7fcb83580dffa4acc623db7c | |
parent | b624e1e9dc012ffb4cfc3cb36b145c93e84c0d14 (diff) | |
parent | 6b4cc784806ac8676a08ecbbeadbd1bfa56073bb (diff) | |
download | gcc-b8c70285c3bb19aea0a7bfc0285271b2b1c0bbdd.zip gcc-b8c70285c3bb19aea0a7bfc0285271b2b1c0bbdd.tar.gz gcc-b8c70285c3bb19aea0a7bfc0285271b2b1c0bbdd.tar.bz2 |
Merge branch 'master' into devel/modula-2.
85 files changed, 1742 insertions, 207 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1599c45..eed4ccd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,223 @@ +2022-05-02 Richard Biener <rguenther@suse.de> + + * tree-scalar-evolution.cc (expression_expensive_p): + Never consider mismatched calls as cheap. + +2022-05-02 Richard Biener <rguenther@suse.de> + + PR tree-optimization/104240 + * tree-vect-slp.cc (op1_op0_map): New. + (vect_get_operand_map): Handle compares. + (vect_build_slp_tree_1): Support swapped operands for + tcc_comparison. + +2022-05-02 Jakub Jelinek <jakub@redhat.com> + + PR debug/105415 + * cfgexpand.cc (expand_debug_expr): Don't make_decl_rtl_for_debug + if there is no symtab node for the VAR_DECL. + +2022-05-02 Sebastian Huber <sebastian.huber@embedded-brains.de> + + * gcov-io.cc (gcov_rewrite): Clear the file error status. + +2022-05-02 Richard Biener <rguenther@suse.de> + + PR tree-optimization/105437 + * tree-vect-slp.cc (vect_schedule_slp_node): Handle the + case where last_stmt alters control flow. + +2022-05-02 Richard Biener <rguenther@suse.de> + + * dojump.cc (do_jump): Use CASE_CONVERT. + * tree-ssa-dom.cc (edge_info::derive_equivalences): Likewise. + +2022-05-02 Jakub Jelinek <jakub@redhat.com> + + * system.h: Include initializer_list. + +2022-05-01 Segher Boessenkool <segher@kernel.crashing.org> + + * config/rs6000/constraints.md (Y constraint): Fix comment. + +2022-05-01 Aldy Hernandez <aldyh@redhat.com> + + * tree-ssanames.cc (set_range_info): Denormalize VR_VARYING to + VR_RANGE before passing a piecewise range to set_range_info_raw. + +2022-04-30 Patrick Palka <ppalka@redhat.com> + + * gengtype.cc (adjust_field_tree_exp): Remove. + (adjust_field_type): Don't handle the "tree_exp" special attribute. + * tree-core.h (struct tree_exp): Remove "special" and "desc" + attributes. Add "length" attribute. + +2022-04-29 Martin Jambor <mjambor@suse.cz> + + PR ipa/100413 + * cgraph.cc (cgraph_node::remove): Release body of the node this + is clone_of if appropriate. + +2022-04-29 Uroš Bizjak <ubizjak@gmail.com> + + PR target/51954 + * config/i386/i386.md (adcl/neg -> sbb peephole): New peephole2. + +2022-04-29 Richard Biener <rguenther@suse.de> + + * gimple-expr.cc (is_gimple_condexpr): Adjust comment. + (canonicalize_cond_expr_cond): Move here from gimple.cc, + allow both COND_EXPR and GIMPLE_COND forms. + * gimple-expr.h (canonicalize_cond_expr_cond): Declare. + * gimple.cc (canonicalize_cond_expr_cond): Remove here. + * gimple.h (canonicalize_cond_expr_cond): Likewise. + * gimple-loop-versioning.cc (loop_versioning::version_loop): + Use is_gimple_condexpr_for_cond. + * tree-parloops.cc (gen_parallel_loop): Likewise. + * tree-ssa-ifcombine.cc (ifcombine_ifandif): Check for + a proper cond expr after canonicalize_cond_expr_cond. + Use is_gimple_condexpr_for_cond where appropriate. + * tree-ssa-loop-manip.cc (determine_exit_conditions): Likewise. + * tree-vect-loop-manip.cc (slpeel_add_loop_guard): Likewise. + +2022-04-29 Richard Biener <rguenther@suse.de> + + * gimple-iterator.h (gsi_after_labels): Add overload for + gimple_seq. + (gsi_start_1): Rename to gsi_start and take a reference. + (gsi_last_1): Likewise. + * gimple-iterator.cc (gsi_for_stmt): Use gsi_start. + * omp-low.cc (lower_rec_input_clauses): Likewise. + (lower_omp_scan): Likewise. + +2022-04-29 Richard Biener <rguenther@suse.de> + + PR tree-optimization/105431 + * tree-ssa-math-opts.cc (powi_as_mults_1): Make n unsigned. + (powi_as_mults): Use absu_hwi. + (gimple_expand_builtin_powi): Remove now pointless n != -n + check. + +2022-04-29 Aldy Hernandez <aldyh@redhat.com> + + * range-op.cc (empty_range_varying): Move to range-op.h. + (range_true): Move to range.h. + (range_false): Same. + (range_true_and_false): Same. + (enum bool_range_state): Move to range-op.h. + (relop_early_resolve): Same. + (operator_equal::op1_op2_relation): Abstract code to... + (equal_op1_op2_relation): ...here. + (operator_not_equal::op1_op2_relation): Abstract code to... + (not_equal_op1_op2_relation): ...here. + (operator_lt::op1_op2_relation): Abstract code to... + (lt_op1_op2_relation): ...here. + (operator_le::op1_op2_relation): Abstract code to... + (le_op1_op2_relation): ...here. + (operator_gt::op1_op2_relation): Abstract code to... + (gt_op1_op2_relation): ...here. + (operator_ge::op1_op2_relation): Abstract code to... + (ge_op1_op2_relation): ...here. + (class range_op_table): Move to range-op.h. + * range-op.h (equal_op1_op2_relation): Moved from range-op.cc. + (not_equal_op1_op2_relation): Same. + (lt_op1_op2_relation): Same. + (le_op1_op2_relation): Same. + (gt_op1_op2_relation): Same. + (ge_op1_op2_relation): Same. + (enum bool_range_state): Same. + (get_bool_state): Same. + (empty_range_varying): Same. + (relop_early_resolve): Same. + (class range_op_table): Same. + * range.h (range_true): Same. + (range_false): Same. + (range_true_and_false): Same. + +2022-04-29 Aldy Hernandez <aldyh@redhat.com> + + * gimple-fold.cc (size_must_be_zero_p): Use reference + instead of pointer + * gimple-ssa-evrp-analyze.cc + (evrp_range_analyzer::record_ranges_from_incoming_edge): Rename + intersect to legacy_verbose_intersect. + * ipa-cp.cc (ipcp_vr_lattice::meet_with_1): Use reference instead + of pointer. + * tree-ssa-dom.cc (dom_jt_simplifier::simplify): Use value_range + instead of value_range_equiv. + * tree-vrp.cc (extract_range_from_plus_minus_expr): Use reference + instead of pointer. + (find_case_label_range): Same. + * value-range-equiv.cc (value_range_equiv::intersect): Rename to... + (value_range_equiv::legacy_verbose_intersect): ...this. + (value_range_equiv::union_): Rename to... + (value_range_equiv::legacy_verbose_union_): ...this. + * value-range-equiv.h (class value_range_equiv): Rename union and + intersect to legacy_verbose_{intersect,union}. + * value-range.cc (irange::union_): Rename to... + (irange::legacy_verbose_union_): ...this. + (irange::intersect): Rename to... + (irange::legacy_verbose_intersect): ...this. + * value-range.h (irange::union_): Rename union_ to + legacy_verbose_union. + (irange::intersect): Rename intersect to legacy_verbose_intersect. + * vr-values.cc (vr_values::update_value_range): Same. + (vr_values::extract_range_for_var_from_comparison_expr): Same. + (vr_values::extract_range_from_cond_expr): Rename union_ to + legacy_verbose_union. + (vr_values::extract_range_from_phi_node): Same. + +2022-04-29 Aldy Hernandez <aldyh@redhat.com> + + * gimple-ssa-evrp-analyze.cc + (evrp_range_analyzer::set_ssa_range_info): Use *range_info methods + that take a range. + * gimple-ssa-sprintf.cc (try_substitute_return_value): Same. + * ipa-prop.cc (ipcp_update_vr): Same. + * tree-inline.cc (remap_ssa_name): Same. + * tree-ssa-copy.cc (fini_copy_prop): Same. + * tree-ssa-math-opts.cc (optimize_spaceship): Same. + * tree-ssa-phiopt.cc (replace_phi_edge_with_variable): Same. + * tree-ssa-pre.cc (insert_into_preds_of_block): Same. + * tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_stmt): Same. + * tree-ssa-strlen.cc (set_strlen_range): Same. + (strlen_pass::handle_builtin_string_cmp): Same. + * tree-ssanames.cc (set_range_info): Make static. + (duplicate_ssa_name_range_info): Make static and add a new variant + calling the static. + * tree-ssanames.h (set_range_info): Remove version taking wide ints. + (duplicate_ssa_name_range_info): Remove version taking a + range_info_def and replace with a version taking SSA names. + * tree-vect-loop-manip.cc (vect_gen_vector_loop_niters): Use *range_info methods + that take a range. + (vect_do_peeling): Same. + * tree-vrp.cc (vrp_asserts::remove_range_assertions): Same. + * vr-values.cc (simplify_truth_ops_using_ranges): Same. + +2022-04-29 Aldy Hernandez <aldyh@redhat.com> + + * value-range.h (irange::irange): Use set_undefined. + +2022-04-29 Aldy Hernandez <aldyh@redhat.com> + + * gimple-range-cache.h (non_null_ref::adjust_range): Do not use + irange::intersect (wide_int, wide_int). + * gimple-range-fold.cc (adjust_pointer_diff_expr): Same. + (adjust_imagpart_expr): Same. + * value-range.h (irange::intersect (wide_int, wide_int)): Make + private. + +2022-04-29 Richard Biener <rguenther@suse.de> + + PR tree-optimization/104322 + * tree-vect-loop.cc (vectorizable_reduction): Remove dead code. + +2022-04-29 Richard Biener <rguenther@suse.de> + + PR middle-end/105376 + * tree.cc (build_real): Special case dconst* arguments + for decimal floating point types. + 2022-04-28 Sebastian Huber <sebastian.huber@embedded-brains.de> * doc/gcov.texi (Profiling and Test Coverage in Freestanding diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4041ef7..22a3091 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20220429 +20220503 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 3a7b8ed..fc01eba 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2022-04-29 Martin Liska <mliska@suse.cz> + + * gnatvsn.ads: Bump Library_Version to 13. + 2022-04-27 Sebastian Huber <sebastian.huber@embedded-brains.de> * tracebak.c: Add support for ARM RTEMS. Add support for RTEMS to PPC diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index d7447d0..a0e53e5 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2022-04-30 Jason Merrill <jason@redhat.com> + + PR c/100545 + * c-attribs.cc (handle_mode_attribute): Copy attributes, aligned, + and typedef. + * c-common.cc (set_underlying_type): Add assert. + 2022-04-26 Patrick Palka <ppalka@redhat.com> PR c++/105304 diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index 111a33f..b1953a4 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -2199,7 +2199,21 @@ handle_mode_attribute (tree *node, tree name, tree args, return NULL_TREE; } - *node = build_qualified_type (typefm, TYPE_QUALS (type)); + /* Copy any quals and attributes to the new type. */ + *node = build_type_attribute_qual_variant (typefm, TYPE_ATTRIBUTES (type), + TYPE_QUALS (type)); + if (TYPE_USER_ALIGN (type)) + *node = build_aligned_type (*node, TYPE_ALIGN (type)); + + tree decl = node[2]; + if (decl && TYPE_NAME (type) == decl) + { + /* Set up the typedef all over again. */ + DECL_ORIGINAL_TYPE (decl) = NULL_TREE; + TREE_TYPE (decl) = *node; + set_underlying_type (decl); + *node = TREE_TYPE (decl); + } } return NULL_TREE; diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index bb0544e..730faa9 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -8153,15 +8153,16 @@ check_missing_format_attribute (tree ltype, tree rtype) void set_underlying_type (tree x) { - if (x == error_mark_node) + if (x == error_mark_node || TREE_TYPE (x) == error_mark_node) return; if (DECL_IS_UNDECLARED_BUILTIN (x) && TREE_CODE (TREE_TYPE (x)) != ARRAY_TYPE) { if (TYPE_NAME (TREE_TYPE (x)) == 0) TYPE_NAME (TREE_TYPE (x)) = x; } - else if (TREE_TYPE (x) != error_mark_node - && DECL_ORIGINAL_TYPE (x) == NULL_TREE) + else if (DECL_ORIGINAL_TYPE (x)) + gcc_checking_assert (TYPE_NAME (TREE_TYPE (x)) == x); + else { tree tt = TREE_TYPE (x); DECL_ORIGINAL_TYPE (x) = tt; diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index d3cc77d..49b9182 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -4565,7 +4565,8 @@ expand_debug_expr (tree exp) || !DECL_NAME (exp) || DECL_HARD_REGISTER (exp) || DECL_IN_CONSTANT_POOL (exp) - || mode == VOIDmode) + || mode == VOIDmode + || symtab_node::get (exp) == NULL) return NULL; op0 = make_decl_rtl_for_debug (exp); diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index 9eb36fe..7aaffd9 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -263,7 +263,7 @@ (match_test "REG_P (XEXP (op, 0))"))) (define_memory_constraint "Y" - "@internal A memory operand for a DQ-form instruction." + "@internal A memory operand for a DS-form instruction." (and (match_code "mem") (match_test "mem_operand_gpr (op, mode)"))) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6304c14..98ae74c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,115 @@ +2022-05-02 Jason Merrill <jason@redhat.com> + + * pt.cc (tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: Copy location. + (do_auto_deduction): Use expr location. + +2022-05-02 Jason Merrill <jason@redhat.com> + + * class.cc (maybe_note_name_used_in_class): Note in all enclosing + classes. Remember location of use. + (note_name_declared_in_class): Adjust. + +2022-05-02 Marek Polacek <polacek@redhat.com> + + * cp-tree.h (uses_template_parms): Adjust declaration. + * pt.cc (uses_template_parms): Return bool. Use a RAII sentinel. + +2022-05-02 Richard Biener <rguenther@suse.de> + + * constexpr.cc (fold_simple_1): Use CASE_CONVERT. + * cp-gimplify.cc (cp_fold): Likewise. + * pt.cc (tsubst_copy): Likewise. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/91618 + PR c++/96604 + * friend.cc (do_friend): Call check_explicit_specialization here. + * decl.cc (grokdeclarator): Not here. + * decl2.cc (check_classfn): Or here. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/104470 + * cp-tree.h (enum tsubst_flags): Add tf_dguide. + * pt.cc (tsubst_aggr_type): Check it. + (tsubst_baselink, tsubst_copy): Check it. + (maybe_dependent_member_ref): Check it. + (instantiate_alias_template): Handle it. + (build_deduction_guide): Set it. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/82980 + * lambda.cc (type_deducible_expression_p): Allow more types. + +2022-04-29 Jason Merrill <jason@redhat.com> + + * decl.cc (cp_finish_decl): Only consider auto for vars. + +2022-04-29 Marek Polacek <polacek@redhat.com> + + PR c++/67048 + * parser.cc (cp_parser_enum_specifier): Warn about empty unnamed enum + only when it's followed by a semicolon. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/80351 + * decl.cc (cp_finish_decl): Check completeness of deduced type. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/102987 + * error.cc (dump_decl) [USING_DECL]: Respect flags. + +2022-04-29 Jason Merrill <jason@redhat.com> + + * error.cc (dump_decl): Check TFF_UNQUALIFIED_NAME. + +2022-04-29 Jakub Jelinek <jakub@redhat.com> + + PR c++/104319 + * parser.cc (cp_parser_template_argument): Treat >= like C++98 >> + after a type id by setting maybe_type_id and aborting tentative + parse. + (cp_parser_enclosed_template_argument_list): Handle + CPP_GREATER_EQ like misspelled CPP_GREATER CPP_RQ and + CPP_RSHIFT_EQ like misspelled CPP_GREATER CPP_GREATER_EQ + or CPP_RSHIFT CPP_EQ or CPP_GREATER CPP_GREATER CPP_EQ. + (cp_parser_next_token_ends_template_argument_p): Return true + also for CPP_GREATER_EQ and CPP_RSHIFT_EQ. + +2022-04-29 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/105426 + * coroutines.cc (register_local_var_uses): Allow promotion of unnamed + temporaries to coroutine frame copies. + +2022-04-29 Jason Merrill <jason@redhat.com> + + * semantics.cc (check_trait_type): Don't check completeness + of element type of array of unknown bound. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/102651 + PR c++/49387 + * rtti.cc (get_tinfo_decl_direct): Don't complete_type. + (emit_tinfo_decl): Update tdesc type if needed. + +2022-04-29 Zhao Wei Liew <zhaoweiliew@gmail.com> + + PR c++/25689 + * call.cc (extract_call_expr): Return a NULL_TREE on failure + instead of asserting. + (build_new_method_call): Suppress -Wparentheses diagnostic for + MODIFY_EXPR. + * semantics.cc (is_assignment_op_expr_p): Add function to check + if an expression is a call to an op= operator expression. + (maybe_convert_cond): Handle the case of a op= operator expression + for the -Wparentheses diagnostic. + 2022-04-28 Patrick Palka <ppalka@redhat.com> PR c++/105425 diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index bfda006..bc94ed4 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -8931,32 +8931,53 @@ is_really_empty_class (tree type, bool ignore_vptr) void maybe_note_name_used_in_class (tree name, tree decl) { - splay_tree names_used; - /* If we're not defining a class, there's nothing to do. */ if (!(innermost_scope_kind() == sk_class && TYPE_BEING_DEFINED (current_class_type) && !LAMBDA_TYPE_P (current_class_type))) return; - /* If there's already a binding for this NAME, then we don't have - anything to worry about. */ - if (lookup_member (current_class_type, name, - /*protect=*/0, /*want_type=*/false, tf_warning_or_error)) - return; + const cp_binding_level *blev = nullptr; + if (const cxx_binding *binding = IDENTIFIER_BINDING (name)) + blev = binding->scope; + const cp_binding_level *lev = current_binding_level; - if (!current_class_stack[current_class_depth - 1].names_used) - current_class_stack[current_class_depth - 1].names_used - = splay_tree_new (splay_tree_compare_pointers, 0, 0); - names_used = current_class_stack[current_class_depth - 1].names_used; + /* Record the binding in the names_used tables for classes inside blev. */ + for (int i = current_class_depth; i > 0; --i) + { + tree type = (i == current_class_depth + ? current_class_type + : current_class_stack[i].type); - splay_tree_insert (names_used, - (splay_tree_key) name, - (splay_tree_value) decl); + for (; lev; lev = lev->level_chain) + { + if (lev == blev) + /* We found the declaration. */ + return; + if (lev->kind == sk_class && lev->this_entity == type) + /* This class is inside the declaration scope. */ + break; + } + + auto &names_used = current_class_stack[i-1].names_used; + if (!names_used) + names_used = splay_tree_new (splay_tree_compare_pointers, 0, 0); + + tree use = build1_loc (input_location, VIEW_CONVERT_EXPR, + TREE_TYPE (decl), decl); + EXPR_LOCATION_WRAPPER_P (use) = 1; + splay_tree_insert (names_used, + (splay_tree_key) name, + (splay_tree_value) use); + } } /* Note that NAME was declared (as DECL) in the current class. Check - to see that the declaration is valid. */ + to see that the declaration is valid under [class.member.lookup]: + + If [the result of a search in T for N at point P] differs from the result of + a search in T for N from immediately after the class-specifier of T, the + program is ill-formed, no diagnostic required. */ void note_name_declared_in_class (tree name, tree decl) @@ -8979,6 +9000,9 @@ note_name_declared_in_class (tree name, tree decl) n = splay_tree_lookup (names_used, (splay_tree_key) name); if (n) { + tree use = (tree) n->value; + location_t loc = EXPR_LOCATION (use); + tree olddecl = OVL_FIRST (TREE_OPERAND (use, 0)); /* [basic.scope.class] A name N used in a class S shall refer to the same declaration @@ -8987,9 +9011,10 @@ note_name_declared_in_class (tree name, tree decl) if (permerror (location_of (decl), "declaration of %q#D changes meaning of %qD", decl, OVL_NAME (decl))) - inform (location_of ((tree) n->value), - "%qD declared here as %q#D", - OVL_NAME (decl), (tree) n->value); + { + inform (loc, "used here to mean %q#D", olddecl); + inform (location_of (olddecl), "declared here" ); + } } } diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 47d5113..c40efa6 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8016,9 +8016,8 @@ fold_simple_1 (tree t) case NEGATE_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: - case NOP_EXPR: case VIEW_CONVERT_EXPR: - case CONVERT_EXPR: + CASE_CONVERT: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIXED_CONVERT_EXPR: diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index e4c2644..b52d9cb 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -2451,9 +2451,8 @@ cp_fold (tree x) case VIEW_CONVERT_EXPR: rval_ops = false; /* FALLTHRU */ - case CONVERT_EXPR: - case NOP_EXPR: case NON_LVALUE_EXPR: + CASE_CONVERT: if (VOID_TYPE_P (TREE_TYPE (x))) { diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e9a3d09..6de29c0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5565,6 +5565,7 @@ enum tsubst_flags { constraint normalization. */ tf_tst_ok = 1 << 12, /* Allow a typename-specifier to name a template (C++17 or later). */ + tf_dguide = 1 << 13, /* Building a deduction guide from a ctor. */ /* Convenient substitution flags combinations. */ tf_warning_or_error = tf_warning | tf_error }; @@ -7311,7 +7312,7 @@ extern tree lookup_template_class (tree, tree, tree, tree, int, tsubst_flags_t); extern tree lookup_template_function (tree, tree); extern tree lookup_template_variable (tree, tree); -extern int uses_template_parms (tree); +extern bool uses_template_parms (tree); extern bool uses_template_parms_level (tree, int); extern bool in_template_function (void); extern bool need_generic_capture (void); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2852093..324498f 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8077,7 +8077,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && (DECL_INITIAL (decl) || init)) DECL_INITIALIZED_IN_CLASS_P (decl) = 1; - if (TREE_CODE (decl) != FUNCTION_DECL + if (VAR_P (decl) && (auto_node = type_uses_auto (type))) { tree d_init; @@ -8105,11 +8105,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, d_init = resolve_nondeduced_context (d_init, tf_warning_or_error); } enum auto_deduction_context adc = adc_variable_type; - if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl)) + if (DECL_DECOMPOSITION_P (decl)) adc = adc_decomp_type; tree outer_targs = NULL_TREE; if (PLACEHOLDER_TYPE_CONSTRAINTS_INFO (auto_node) - && VAR_P (decl) && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && !DECL_FUNCTION_SCOPE_P (decl)) @@ -8129,6 +8128,17 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, TREE_TYPE (decl) = error_mark_node; return; } + /* As in start_decl_1, complete so TREE_READONLY is set properly. */ + if (!processing_template_decl + && !type_uses_auto (type) + && !COMPLETE_TYPE_P (complete_type (type))) + { + error_at (location_of (decl), + "deduced type %qT for %qD is incomplete", type, decl); + cxx_incomplete_type_inform (type); + TREE_TYPE (decl) = error_mark_node; + return; + } cp_apply_type_quals_to_decl (cp_type_quals (type), decl); } @@ -14132,15 +14142,6 @@ grokdeclarator (const cp_declarator *declarator, So set it here. */ funcdef_flag = true; - if (template_class_depth (current_class_type) == 0) - { - decl = check_explicit_specialization - (unqualified_id, decl, template_count, - 2 * funcdef_flag + 4); - if (decl == error_mark_node) - return error_mark_node; - } - decl = do_friend (ctype, unqualified_id, decl, flags, funcdef_flag); return decl; diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index d2b2920..ae743c8 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -799,14 +799,9 @@ check_classfn (tree ctype, tree function, tree template_parms) is replaced with the specialization chosen by deduction from the friend declaration or discarded if deduction fails." - So ask check_explicit_specialization to find a matching template. */ + So tell check_explicit_specialization to look for a match. */ SET_DECL_IMPLICIT_INSTANTIATION (function); - tree spec = check_explicit_specialization (DECL_NAME (function), - function, /* tcount */0, - /* friend flag */4, - /* attrlist */NULL_TREE); - if (spec != error_mark_node) - matched = spec; + matched = function; } if (!matched) diff --git a/gcc/cp/friend.cc b/gcc/cp/friend.cc index acbe0ec..124ed4f 100644 --- a/gcc/cp/friend.cc +++ b/gcc/cp/friend.cc @@ -506,6 +506,7 @@ do_friend (tree ctype, tree declarator, tree decl, error ("friend declaration %qD may not have virt-specifiers", decl); + tree orig_declarator = declarator; if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) { declarator = TREE_OPERAND (declarator, 0); @@ -513,32 +514,33 @@ do_friend (tree ctype, tree declarator, tree decl, declarator = OVL_NAME (declarator); } + /* CLASS_TEMPLATE_DEPTH counts the number of template headers for + the enclosing class. FRIEND_DEPTH counts the number of template + headers used for this friend declaration. TEMPLATE_MEMBER_P is + true if a template header in FRIEND_DEPTH is intended for + DECLARATOR. For example, the code + + template <class T> struct A { + template <class U> struct B { + template <class V> template <class W> + friend void C<V>::f(W); + }; + }; + + will eventually give the following results + + 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U'). + 2. FRIEND_DEPTH equals 2 (for `V' and `W'). + 3. CTYPE_DEPTH equals 1 (for `V'). + 4. TEMPLATE_MEMBER_P is true (for `W'). */ + + int class_template_depth = template_class_depth (current_class_type); + int friend_depth = current_template_depth - class_template_depth; + int ctype_depth = num_template_headers_for_class (ctype); + bool template_member_p = friend_depth > ctype_depth; + if (ctype) { - /* CLASS_TEMPLATE_DEPTH counts the number of template headers for - the enclosing class. FRIEND_DEPTH counts the number of template - headers used for this friend declaration. TEMPLATE_MEMBER_P is - true if a template header in FRIEND_DEPTH is intended for - DECLARATOR. For example, the code - - template <class T> struct A { - template <class U> struct B { - template <class V> template <class W> - friend void C<V>::f(W); - }; - }; - - will eventually give the following results - - 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U'). - 2. FRIEND_DEPTH equals 2 (for `V' and `W'). - 3. TEMPLATE_MEMBER_P is true (for `W'). */ - - int class_template_depth = template_class_depth (current_class_type); - int friend_depth = current_template_depth - class_template_depth; - /* We will figure this out later. */ - bool template_member_p = false; - tree cname = TYPE_NAME (ctype); if (TREE_CODE (cname) == TYPE_DECL) cname = DECL_NAME (cname); @@ -549,13 +551,6 @@ do_friend (tree ctype, tree declarator, tree decl, grokclassfn (ctype, decl, flags); - if (friend_depth) - { - if (!uses_template_parms_level (ctype, class_template_depth - + friend_depth)) - template_member_p = true; - } - /* A nested class may declare a member of an enclosing class to be a friend, so we do lookup here even if CTYPE is in the process of being defined. */ @@ -584,9 +579,6 @@ do_friend (tree ctype, tree declarator, tree decl, || (class_template_depth && friend_depth)) && decl && TREE_CODE (decl) == FUNCTION_DECL) decl = DECL_TI_TEMPLATE (decl); - - if (decl) - add_friend (current_class_type, decl, /*complain=*/true); } else error ("member %qD declared as friend before type %qT defined", @@ -595,7 +587,6 @@ do_friend (tree ctype, tree declarator, tree decl, else { /* Namespace-scope friend function. */ - int is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P (); if (funcdef_flag) SET_DECL_FRIEND_CONTEXT (decl, current_class_type); @@ -606,12 +597,11 @@ do_friend (tree ctype, tree declarator, tree decl, arguments before push_template_decl adds a reference to the containing template class. */ int warn = (warn_nontemplate_friend - && ! funcdef_flag && ! is_friend_template + && ! funcdef_flag && ! friend_depth && current_template_parms && uses_template_parms (decl)); - if (is_friend_template - || template_class_depth (current_class_type) != 0) + if (friend_depth || class_template_depth) /* We can't call pushdecl for a template class, since in general, such a declaration depends on template parameters. Instead, we call pushdecl when the class @@ -651,15 +641,27 @@ do_friend (tree ctype, tree declarator, tree decl, } } } - - if (decl == error_mark_node) - return error_mark_node; - - add_friend (current_class_type, - is_friend_template ? DECL_TI_TEMPLATE (decl) : decl, - /*complain=*/true); } + if (decl == error_mark_node) + return error_mark_node; + + if (!class_template_depth && DECL_IMPLICIT_INSTANTIATION (decl)) + /* "[if no non-template match is found,] each remaining function template + is replaced with the specialization chosen by deduction from the + friend declaration or discarded if deduction fails." + + set_decl_namespace or check_classfn set DECL_IMPLICIT_INSTANTIATION to + indicate that we need a template match, so ask + check_explicit_specialization to find one. */ + decl = (check_explicit_specialization + (orig_declarator, decl, ctype_depth, + 2 * funcdef_flag + 4)); + + add_friend (current_class_type, + (!ctype && friend_depth) ? DECL_TI_TEMPLATE (decl) : decl, + /*complain=*/true); + return decl; } diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 65579ed..10834d6 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -195,10 +195,9 @@ type_deducible_expression_p (tree expr) || TREE_CODE (expr) == EXPR_PACK_EXPANSION) return false; tree t = non_reference (TREE_TYPE (expr)); - if (!t) return false; - while (TREE_CODE (t) == POINTER_TYPE) - t = TREE_TYPE (t); - return currently_open_class (t); + return (t && TREE_CODE (t) != TYPE_PACK_EXPANSION + && !WILDCARD_TYPE_P (t) && !LAMBDA_TYPE_P (t) + && !type_uses_auto (t)); } /* Returns the type to use for the FIELD_DECL corresponding to the diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index ee69934..a5cbb3e 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -21012,7 +21012,9 @@ cp_parser_enum_specifier (cp_parser* parser) /* If the next token is not '}', then there are some enumerators. */ else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE)) { - if (is_unnamed && !scoped_enum_p) + if (is_unnamed && !scoped_enum_p + /* Don't warn for enum {} a; here. */ + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SEMICOLON)) pedwarn (type_start_token->location, OPT_Wpedantic, "ISO C++ forbids empty unnamed enum"); } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 81f7ef5..3edee50 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10884,35 +10884,30 @@ find_template_parameters (tree t, tree ctx_parms) /* Returns true if T depends on any template parameter. */ -int +bool uses_template_parms (tree t) { - if (t == NULL_TREE) + if (t == NULL_TREE || t == error_mark_node) + return false; + + /* Namespaces can't depend on any template parameters. */ + if (TREE_CODE (t) == NAMESPACE_DECL) return false; - bool dependent_p; - int saved_processing_template_decl; + processing_template_decl_sentinel ptds (/*reset*/false); + ++processing_template_decl; - saved_processing_template_decl = processing_template_decl; - if (!saved_processing_template_decl) - processing_template_decl = 1; if (TYPE_P (t)) - dependent_p = dependent_type_p (t); + return dependent_type_p (t); else if (TREE_CODE (t) == TREE_VEC) - dependent_p = any_dependent_template_arguments_p (t); + return any_dependent_template_arguments_p (t); else if (TREE_CODE (t) == TREE_LIST) - dependent_p = (uses_template_parms (TREE_VALUE (t)) - || uses_template_parms (TREE_CHAIN (t))); + return (uses_template_parms (TREE_VALUE (t)) + || uses_template_parms (TREE_CHAIN (t))); else if (TREE_CODE (t) == TYPE_DECL) - dependent_p = dependent_type_p (TREE_TYPE (t)); - else if (t == error_mark_node || TREE_CODE (t) == NAMESPACE_DECL) - dependent_p = false; + return dependent_type_p (TREE_TYPE (t)); else - dependent_p = instantiation_dependent_expression_p (t); - - processing_template_decl = saved_processing_template_decl; - - return dependent_p; + return instantiation_dependent_expression_p (t); } /* Returns true iff we're processing an incompletely instantiated function @@ -13730,8 +13725,8 @@ tsubst_aggr_type (tree t, complain, in_decl); if (argvec == error_mark_node) r = error_mark_node; - else if (!entering_scope - && cxx_dialect >= cxx17 && dependent_scope_p (context)) + else if (!entering_scope && (complain & tf_dguide) + && dependent_scope_p (context)) { /* See maybe_dependent_member_ref. */ tree name = TYPE_IDENTIFIER (t); @@ -16497,7 +16492,7 @@ tsubst_baselink (tree baselink, tree object_type, name = make_conv_op_name (optype); /* See maybe_dependent_member_ref. */ - if (dependent_scope_p (qualifying_scope)) + if ((complain & tf_dguide) && dependent_scope_p (qualifying_scope)) { if (template_id_p) name = build2 (TEMPLATE_ID_EXPR, unknown_type_node, name, @@ -16817,7 +16812,7 @@ static tree maybe_dependent_member_ref (tree t, tree args, tsubst_flags_t complain, tree in_decl) { - if (cxx_dialect < cxx17) + if (!(complain & tf_dguide)) return NULL_TREE; tree ctx = context_for_name_lookup (t); @@ -17075,7 +17070,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) have to substitute this with one having context `D<int>'. */ tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl); - if (dependent_scope_p (context)) + if ((complain & tf_dguide) && dependent_scope_p (context)) { /* When rewriting a constructor into a deduction guide, a non-dependent name can become dependent, so memtmpl<args> @@ -17152,8 +17147,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case STATIC_CAST_EXPR: case DYNAMIC_CAST_EXPR: case IMPLICIT_CONV_EXPR: - case CONVERT_EXPR: - case NOP_EXPR: + CASE_CONVERT: { tsubst_flags_t tcomplain = complain; if (code == CAST_EXPR) @@ -20097,6 +20091,7 @@ tsubst_copy_and_build (tree t, object = NULL_TREE; tree tid = lookup_template_function (templ, targs); + protected_set_expr_location (tid, EXPR_LOCATION (t)); if (object) RETURN (build3 (COMPONENT_REF, TREE_TYPE (tid), @@ -21715,6 +21710,21 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain) if (tmpl == error_mark_node || args == error_mark_node) return error_mark_node; + /* See maybe_dependent_member_ref. */ + if (complain & tf_dguide) + { + tree ctx = tsubst_aggr_type (DECL_CONTEXT (tmpl), args, complain, + tmpl, true); + if (dependent_scope_p (ctx)) + { + tree name = DECL_NAME (tmpl); + tree fullname = build_nt (TEMPLATE_ID_EXPR, name, + INNERMOST_TEMPLATE_ARGS (args)); + tree tname = build_typename_type (ctx, name, fullname, typename_type); + return TYPE_NAME (tname); + } + } + args = coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl), args, tmpl, complain, @@ -29279,6 +29289,8 @@ build_deduction_guide (tree type, tree ctor, tree outer_args, tsubst_flags_t com ++processing_template_decl; bool ok = true; + complain |= tf_dguide; + fn_tmpl = (TREE_CODE (ctor) == TEMPLATE_DECL ? ctor : DECL_TI_TEMPLATE (ctor)); @@ -30170,6 +30182,8 @@ do_auto_deduction (tree type, tree init, tree auto_node, /* Nothing we can do with this, even in deduction context. */ return type; + location_t loc = cp_expr_loc_or_input_loc (init); + /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with @@ -30184,9 +30198,9 @@ do_auto_deduction (tree type, tree init, tree auto_node, { if (complain & tf_warning_or_error) { - if (permerror (input_location, "direct-list-initialization of " + if (permerror (loc, "direct-list-initialization of " "%<auto%> requires exactly one element")) - inform (input_location, + inform (loc, "for deduction to %<std::initializer_list%>, use copy-" "list-initialization (i.e. add %<=%> before the %<{%>)"); } @@ -30277,9 +30291,10 @@ do_auto_deduction (tree type, tree init, tree auto_node, && (auto_node == DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl)) && LAMBDA_FUNCTION_P (current_function_decl)) - error ("unable to deduce lambda return type from %qE", init); + error_at (loc, "unable to deduce lambda return type from %qE", + init); else - error ("unable to deduce %qT from %qE", type, init); + error_at (loc, "unable to deduce %qT from %qE", type, init); type_unification_real (tparms, targs, parms, &init, 1, 0, DEDUCE_CALL, NULL, /*explain_p=*/true); @@ -30351,23 +30366,23 @@ do_auto_deduction (tree type, tree init, tree auto_node, { case adc_unspecified: case adc_unify: - error("placeholder constraints not satisfied"); + error_at (loc, "placeholder constraints not satisfied"); break; case adc_variable_type: case adc_decomp_type: - error ("deduced initializer does not satisfy " - "placeholder constraints"); + error_at (loc, "deduced initializer does not satisfy " + "placeholder constraints"); break; case adc_return_type: - error ("deduced return type does not satisfy " - "placeholder constraints"); + error_at (loc, "deduced return type does not satisfy " + "placeholder constraints"); break; case adc_requirement: - error ("deduced expression type does not satisfy " - "placeholder constraints"); + error_at (loc, "deduced expression type does not satisfy " + "placeholder constraints"); break; } - diagnose_constraints (input_location, auto_node, full_targs); + diagnose_constraints (loc, auto_node, full_targs); } return error_mark_node; } diff --git a/gcc/dojump.cc b/gcc/dojump.cc index 0c880d6..17a73da 100644 --- a/gcc/dojump.cc +++ b/gcc/dojump.cc @@ -421,14 +421,12 @@ do_jump (tree exp, rtx_code_label *if_false_label, break; #endif - case NOP_EXPR: + CASE_CONVERT: if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF) goto normal; - /* FALLTHRU */ - case CONVERT_EXPR: /* If we are narrowing the operand, we have to do the compare in the narrower mode. */ if ((TYPE_PRECISION (TREE_TYPE (exp)) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 017f3e6..fbae4f0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,21 @@ +2022-05-02 Sandra Loosemore <sandra@codesourcery.com> + + * trans-openmp.cc (gfc_trans_omp_critical): Set location on OMP + tree node. + (gfc_trans_omp_do): Likewise. + (gfc_trans_omp_masked): Likewise. + (gfc_trans_omp_do_simd): Likewise. + (gfc_trans_omp_scope): Likewise. + (gfc_trans_omp_taskgroup): Likewise. + (gfc_trans_omp_taskwait): Likewise. + (gfc_trans_omp_distribute): Likewise. + (gfc_trans_omp_taskloop): Likewise. + (gfc_trans_omp_master_masked_taskloop): Likewise. + +2022-04-29 Thomas Koenig <tkoenig@gcc.gnu.org> + + * gfortran.texi: Fix exchanged period and letter. + 2022-04-28 Thomas Koenig <tkoenig@gcc.gnu.org> * gfortran.texi: Mention r16_ieee and r16_ibm. diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 6f622fb..d34e0b5 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -723,7 +723,7 @@ others with commas. Those are A missing mode for an exception is taken to mean @code{BIG_ENDIAN}. Examples of values for @env{GFORTRAN_CONVERT_UNIT} are: @itemize @w{} -@item @code{'big_endian'} Do all unformatted I/O in big_endian mod.e +@item @code{'big_endian'} Do all unformatted I/O in big_endian mode. @item @code{'little_endian;native:10-20,25'} Do all unformatted I/O in little_endian mode, except for units 10 to 20 and 25, which are in native format. diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 43d59ab..7f3ac97 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -5014,6 +5014,7 @@ gfc_trans_omp_critical (gfc_code *code) name = get_identifier (code->ext.omp_clauses->critical_name); gfc_start_block (&block); stmt = make_node (OMP_CRITICAL); + SET_EXPR_LOCATION (stmt, gfc_get_location (&code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_CRITICAL_BODY (stmt) = gfc_trans_code (code->block->next); OMP_CRITICAL_NAME (stmt) = name; @@ -5046,6 +5047,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, unsigned ix; vec<tree, va_heap, vl_embed> *saved_doacross_steps = doacross_steps; gfc_expr_list *tile = do_clauses ? do_clauses->tile_list : clauses->tile_list; + gfc_code *orig_code = code; /* Both collapsed and tiled loops are lowered the same way. In OpenACC, those clauses are not compatible, so prioritize the tile @@ -5400,6 +5402,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, default: gcc_unreachable (); } + SET_EXPR_LOCATION (stmt, gfc_get_location (&orig_code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_FOR_BODY (stmt) = gfc_finish_block (&body); OMP_FOR_CLAUSES (stmt) = omp_clauses; @@ -5672,6 +5675,7 @@ gfc_trans_omp_masked (gfc_code *code, gfc_omp_clauses *clauses) gfc_start_block (&block); tree omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc); tree stmt = make_node (OMP_MASKED); + SET_EXPR_LOCATION (stmt, gfc_get_location (&code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_MASKED_BODY (stmt) = body; OMP_MASKED_CLAUSES (stmt) = omp_clauses; @@ -6446,6 +6450,7 @@ gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock, if (flag_openmp) { stmt = make_node (OMP_FOR); + SET_EXPR_LOCATION (stmt, gfc_get_location (&code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_FOR_BODY (stmt) = body; OMP_FOR_CLAUSES (stmt) = omp_do_clauses; @@ -6618,6 +6623,7 @@ gfc_trans_omp_scope (gfc_code *code) tree omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses, code->loc); tree stmt = make_node (OMP_SCOPE); + SET_EXPR_LOCATION (stmt, gfc_get_location (&code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_SCOPE_BODY (stmt) = body; OMP_SCOPE_CLAUSES (stmt) = omp_clauses; @@ -6693,6 +6699,7 @@ gfc_trans_omp_taskgroup (gfc_code *code) gfc_start_block (&block); tree body = gfc_trans_code (code->block->next); tree stmt = make_node (OMP_TASKGROUP); + SET_EXPR_LOCATION (stmt, gfc_get_location (&code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_TASKGROUP_BODY (stmt) = body; OMP_TASKGROUP_CLAUSES (stmt) = gfc_trans_omp_clauses (&block, @@ -6713,6 +6720,7 @@ gfc_trans_omp_taskwait (gfc_code *code) stmtblock_t block; gfc_start_block (&block); tree stmt = make_node (OMP_TASK); + SET_EXPR_LOCATION (stmt, gfc_get_location (&code->loc)); TREE_TYPE (stmt) = void_type_node; OMP_TASK_BODY (stmt) = NULL_TREE; OMP_TASK_CLAUSES (stmt) = gfc_trans_omp_clauses (&block, @@ -6790,6 +6798,7 @@ gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa) if (flag_openmp) { tree distribute = make_node (OMP_DISTRIBUTE); + SET_EXPR_LOCATION (distribute, gfc_get_location (&code->loc)); TREE_TYPE (distribute) = void_type_node; OMP_FOR_BODY (distribute) = stmt; OMP_FOR_CLAUSES (distribute) = omp_clauses; @@ -7010,6 +7019,7 @@ gfc_trans_omp_taskloop (gfc_code *code, gfc_exec_op op) if (flag_openmp) { tree taskloop = make_node (OMP_TASKLOOP); + SET_EXPR_LOCATION (taskloop, gfc_get_location (&code->loc)); TREE_TYPE (taskloop) = void_type_node; OMP_FOR_BODY (taskloop) = stmt; OMP_FOR_CLAUSES (taskloop) = omp_clauses; @@ -7055,6 +7065,7 @@ gfc_trans_omp_master_masked_taskloop (gfc_code *code, gfc_exec_op op) &clausesa[GFC_OMP_SPLIT_MASKED], code->loc); tree msk = make_node (OMP_MASKED); + SET_EXPR_LOCATION (msk, gfc_get_location (&code->loc)); TREE_TYPE (msk) = void_type_node; OMP_MASKED_BODY (msk) = stmt; OMP_MASKED_CLAUSES (msk) = clauses; diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc index fdf745e..62032cc 100644 --- a/gcc/gcov-io.cc +++ b/gcc/gcov-io.cc @@ -79,11 +79,14 @@ gcov_is_error (void) } #if IN_LIBGCOV -/* Move to beginning of file and initialize for writing. */ +/* Move to beginning of file, initialize for writing, and clear file error + status. */ + GCOV_LINKAGE inline void gcov_rewrite (void) { gcov_var.mode = -1; + gcov_var.error = GCOV_FILE_NO_ERROR; fseek (gcov_var.file, 0L, SEEK_SET); } #endif diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc index 386ae1b..793ebd7 100644 --- a/gcc/gengtype.cc +++ b/gcc/gengtype.cc @@ -511,7 +511,6 @@ pair_p typedefs = NULL; type_p structures = NULL; pair_p variables = NULL; -static type_p adjust_field_tree_exp (type_p t, options_p opt); static type_p adjust_field_rtx_def (type_p t, options_p opt); /* Define S as a typedef to T at POS. */ @@ -1384,36 +1383,6 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) nodot, NULL); } -/* Handle `special("tree_exp")'. This is a special case for - field `operands' of struct tree_exp, which although it claims to contain - pointers to trees, actually sometimes contains pointers to RTL too. - Passed T, the old type of the field, and OPT its options. Returns - a new type for the field. */ - -static type_p -adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED) -{ - pair_p flds; - options_p nodot; - - if (t->kind != TYPE_ARRAY) - { - error_at_line (&lexer_line, - "special `tree_exp' must be applied to an array"); - return &string_type; - } - - nodot = create_string_option (NULL, "dot", ""); - - flds = create_field (NULL, t, ""); - flds->opt = create_string_option (nodot, "length", - "TREE_OPERAND_LENGTH ((tree) &%0)"); - flds->opt = create_string_option (flds->opt, "default", ""); - - return new_structure ("tree_exp_subunion", TYPE_UNION, &lexer_line, flds, - nodot, NULL); -} - /* Perform any special processing on a type T, about to become the type of a field. Return the appropriate type for the field. At present: @@ -1447,9 +1416,7 @@ adjust_field_type (type_p t, options_p opt) && opt->kind == OPTION_STRING) { const char *special_name = opt->info.string; - if (strcmp (special_name, "tree_exp") == 0) - t = adjust_field_tree_exp (t, opt); - else if (strcmp (special_name, "rtx_def") == 0) + if (strcmp (special_name, "rtx_def") == 0) t = adjust_field_rtx_def (t, opt); else error_at_line (&lexer_line, "unknown special `%s'", special_name); diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index a43fa47..8767038 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -3982,6 +3982,7 @@ omp_runtime_api_call (const_tree fndecl) "alloc", "calloc", "free", + "get_mapped_ptr", "realloc", "target_alloc", "target_associate_ptr", diff --git a/gcc/opts.cc b/gcc/opts.cc index e5e3119..2ffbf42 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -35,6 +35,9 @@ along with GCC; see the file COPYING3. If not see #include "version.h" #include "selftest.h" +/* In this file all option sets are explicit. */ +#undef OPTION_SET_P + static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff); /* Names of fundamental debug info formats indexed by enum @@ -1317,7 +1320,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, debug_info_level = DINFO_LEVEL_NONE; } - if (!OPTION_SET_P (debug_nonbind_markers_p)) + if (!opts_set->x_debug_nonbind_markers_p) debug_nonbind_markers_p = (optimize && debug_info_level >= DINFO_LEVEL_NORMAL @@ -1326,15 +1329,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* Note -fvar-tracking is enabled automatically with OPT_LEVELS_1_PLUS and so we need to drop it if we are called from optimize attribute. */ - if (debug_info_level == DINFO_LEVEL_NONE - && !OPTION_SET_P (flag_var_tracking)) + if (debug_info_level < DINFO_LEVEL_NORMAL) flag_var_tracking = false; /* One could use EnabledBy, but it would lead to a circular dependency. */ - if (!OPTION_SET_P (flag_var_tracking_uninit)) + if (!opts_set->x_flag_var_tracking_uninit) flag_var_tracking_uninit = flag_var_tracking; - if (!OPTION_SET_P (flag_var_tracking_assignments)) + if (!opts_set->x_flag_var_tracking_assignments) flag_var_tracking_assignments = (flag_var_tracking && !(flag_selective_scheduling || flag_selective_scheduling2)); diff --git a/gcc/system.h b/gcc/system.h index c25cd64..c5562cc 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -239,6 +239,7 @@ extern int errno; # include <functional> #endif # include <cstring> +# include <initializer_list> # include <new> # include <utility> # include <type_traits> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2a7aa6b..4646b72 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,135 @@ +2022-05-02 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp2a/lambda-pack-init7.C: Check column number. + +2022-05-02 Jason Merrill <jason@redhat.com> + + * g++.dg/lookup/name-clash13.C: New test. + * g++.dg/lookup/name-clash14.C: New test. + * g++.dg/lookup/name-clash15.C: New test. + * g++.dg/lookup/name-clash16.C: New test. + +2022-05-02 H.J. Lu <hjl.tools@gmail.com> + + PR testsuite/105433 + * gcc.target/i386/iamcu/asm-support.S: Add .note.GNU-stack. + * gcc.target/x86_64/abi/asm-support.S: Likewise. + * gcc.target/x86_64/abi/avx/asm-support.S: Likewise. + * gcc.target/x86_64/abi/avx512f/asm-support.S: Likewise. + * gcc.target/x86_64/abi/avx512fp16/asm-support.S: Likewise. + * gcc.target/x86_64/abi/avx512fp16/m256h/asm-support.S: Likewise. + * gcc.target/x86_64/abi/avx512fp16/m512h/asm-support.S: Likewise. + * gcc.target/x86_64/abi/ms-sysv/do-test.S: Likewise. + +2022-05-02 Richard Biener <rguenther@suse.de> + + PR tree-optimization/104240 + * gcc.dg/vect/bb-slp-pr104240.c: New testcase. + +2022-05-02 Jakub Jelinek <jakub@redhat.com> + + PR debug/105415 + * gcc.dg/pr105415.c: New test. + +2022-05-02 Richard Biener <rguenther@suse.de> + + PR tree-optimization/105437 + * g++.dg/vect/pr105437.cc: New testcase. + +2022-04-30 Jason Merrill <jason@redhat.com> + + PR c/100545 + * c-c++-common/attr-mode-1.c: New test. + * c-c++-common/attr-mode-2.c: New test. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/104470 + * g++.dg/cpp2a/explicit11.C: Second example also ill-formed. + * g++.dg/cpp2a/class-deduction-alias12.C: New test. + +2022-04-29 Marek Polacek <polacek@redhat.com> + + PR c++/67048 + * g++.dg/cpp0x/enum42.C: New test. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/80351 + * g++.dg/cpp0x/constexpr-77482.C: Adjust message. + * g++.dg/cpp1y/auto-fn27.C: Likewise. + * g++.dg/cpp1y/lambda-generic-variadic22.C: Likewise. + * g++.dg/cpp1z/decomp54.C: Likewise. + * g++.dg/cpp0x/initlist-const1.C: New test. + * g++.dg/warn/Wunused-var-37.C: New test. + * g++.dg/warn/Wunused-var-38.C: New test. + * g++.dg/warn/Wunused-var-39.C: New test. + +2022-04-29 Martin Jambor <mjambor@suse.cz> + + PR ipa/100413 + * g++.dg/ipa/pr100413.C: New test. + +2022-04-29 Andre Vieira <andre.simoesdiasvieira@arm.com> + + PR tree-optimization/105219 + * gcc.dg/vect/pr105219.c: Add aarch64 target option. + +2022-04-29 Marek Polacek <polacek@redhat.com> + + PR c++/83596 + * g++.dg/cpp1z/nontype5.C: New test. + +2022-04-29 Marek Polacek <polacek@redhat.com> + + PR c++/78244 + * g++.dg/cpp0x/Wnarrowing20.C: New test. + +2022-04-29 Marek Polacek <polacek@redhat.com> + + PR c++/71424 + * g++.dg/cpp0x/initlist-array15.C: New test. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/102987 + * g++.dg/diagnostic/using1.C: Check pretty-printing. + +2022-04-29 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/alias-decl-1.C: Expect qualified name. + +2022-04-29 Jakub Jelinek <jakub@redhat.com> + + PR c++/104319 + * g++.dg/parse/template28.C: Adjust expected diagnostics. + * g++.dg/parse/template30.C: New test. + +2022-04-29 Uroš Bizjak <ubizjak@gmail.com> + + PR target/51954 + * gcc.target/i386/pr51954.c: New test. + +2022-04-29 Richard Biener <rguenther@suse.de> + + PR middle-end/105376 + * gcc.dg/pr105376.c: New testcase. + +2022-04-29 Jason Merrill <jason@redhat.com> + + * g++.dg/ext/unary_trait_incomplete.C: Adjust. + +2022-04-29 Jason Merrill <jason@redhat.com> + + PR c++/102651 + PR c++/49387 + * g++.dg/rtti/typeid-complete1.C: New test. + +2022-04-29 Zhao Wei Liew <zhaoweiliew@gmail.com> + + PR c++/25689 + * g++.dg/warn/Wparentheses-31.C: New test. + 2022-04-28 Sebastian Huber <sebastian.huber@embedded-brains.de> * gcc.dg/gcov-info-to-gcda.c: Test __gcov_filename_to_gcfn(). diff --git a/gcc/testsuite/c-c++-common/attr-mode-1.c b/gcc/testsuite/c-c++-common/attr-mode-1.c new file mode 100644 index 0000000..04a2431 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-mode-1.c @@ -0,0 +1,4 @@ +// PR c/100545 +// { dg-additional-options -g } + +typedef int fatp_t __attribute__((aligned, mode(SI))); diff --git a/gcc/testsuite/c-c++-common/attr-mode-2.c b/gcc/testsuite/c-c++-common/attr-mode-2.c new file mode 100644 index 0000000..de65f49 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-mode-2.c @@ -0,0 +1,4 @@ +typedef int I; +int x; +I y __attribute__ ((mode(QI))); +extern I x; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-77482.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-77482.C index 6f5c916..bed66c7 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-77482.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-77482.C @@ -3,4 +3,4 @@ constexpr auto x; // { dg-error "declaration\[^\n\r]*has no initializer" } extern struct S s; -constexpr auto y = s; // { dg-error "has incomplete type" } +constexpr auto y = s; // { dg-error "incomplete" } diff --git a/gcc/testsuite/g++.dg/cpp0x/enum42.C b/gcc/testsuite/g++.dg/cpp0x/enum42.C new file mode 100644 index 0000000..05b372a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum42.C @@ -0,0 +1,7 @@ +// PR c++/67048 +// { dg-do compile { target c++11 } } +// { dg-options -Wpedantic } + +typedef enum {} X; +enum {} x; +enum {} y, z; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C new file mode 100644 index 0000000..de80731 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-const1.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } + +#include <initializer_list> + +const auto x = { 1, 2 }; + +// { dg-final { scan-assembler-not {\.data} } } diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C index c019d9e..b22647a 100644 --- a/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C @@ -31,7 +31,7 @@ F<T>::bar (const G &) { auto s = I; typedef decltype (s) L; - auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:declared void" } + auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:incomplete|void" } } struct B { typedef int G; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C index 670c598..9c02d07 100644 --- a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C @@ -4,7 +4,7 @@ template <typename T> auto f (T) { - auto a = [](auto ... i) // { dg-prune-output "incomplete type" } + auto a = [](auto ... i) // { dg-prune-output "incomplete" } { int x[][i] = { 0 }; // { dg-error "not expanded" } }(); diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp54.C b/gcc/testsuite/g++.dg/cpp1z/decomp54.C index 1bee772..1094329 100644 --- a/gcc/testsuite/g++.dg/cpp1z/decomp54.C +++ b/gcc/testsuite/g++.dg/cpp1z/decomp54.C @@ -3,9 +3,9 @@ // { dg-options "" } extern int a[]; -auto [b] { a }; // { dg-error "has incomplete type" } +auto [b] { a }; // { dg-error "incomplete" } // { dg-warning "only available with" "" { target c++14_down } .-1 } -auto [c] = a; // { dg-error "has incomplete type" } +auto [c] = a; // { dg-error "incomplete" } // { dg-warning "only available with" "" { target c++14_down } .-1 } extern int d[0]; auto [e] { d }; // { dg-error "too many initializers for" } diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C new file mode 100644 index 0000000..725e758 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C @@ -0,0 +1,23 @@ +// PR c++/104470 +// { dg-do compile { target c++20 } } + +template<typename _Types> +class variant +{ + template<typename _Tp> + static constexpr int __accepted_index = 0; + template<int _Np> + using __to_type = int; + template<typename _Tp> + using __accepted_type = __to_type<__accepted_index<_Tp>>; + template<typename _Tp, typename _Tj = __accepted_type<_Tp>> + variant(_Tp __t) { } +}; +template <typename T> +struct Foo +{ + T value; +}; +template <typename T> +using V = variant<Foo<T>>; +V e = Foo{1}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/cpp2a/explicit11.C b/gcc/testsuite/g++.dg/cpp2a/explicit11.C index 2df42cd..b6adfd0 100644 --- a/gcc/testsuite/g++.dg/cpp2a/explicit11.C +++ b/gcc/testsuite/g++.dg/cpp2a/explicit11.C @@ -26,4 +26,4 @@ struct B { template<typename U> B(U, TA<U>); }; -B b{(int *)0, (char *)0}; +B b{(int *)0, (char *)0}; // { dg-error "deduction|no match" } diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init7.C b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init7.C index f3c3899..face725 100644 --- a/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init7.C +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init7.C @@ -8,7 +8,7 @@ struct S {}; template <typename... Args> void foo(Args&&... args) { - [...args = forward<Args> /*(args)*/] { // { dg-error "" } + [...args = forward<Args> /*(args)*/] { // { dg-error "14:" } [](auto...) { } (forward<Args>(args)...); }; } diff --git a/gcc/testsuite/g++.dg/lookup/name-clash13.C b/gcc/testsuite/g++.dg/lookup/name-clash13.C new file mode 100644 index 0000000..ce43435 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/name-clash13.C @@ -0,0 +1,7 @@ +typedef int T; +struct A { + struct B { + static T t; + }; + typedef float T; // { dg-error "changes meaning" } +}; diff --git a/gcc/testsuite/g++.dg/lookup/name-clash14.C b/gcc/testsuite/g++.dg/lookup/name-clash14.C new file mode 100644 index 0000000..71305ba --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/name-clash14.C @@ -0,0 +1,9 @@ +const int x = 24; +struct A +{ + struct B + { + enum { E = x }; + }; + static const int x = 42; // { dg-error "changes meaning" } +}; diff --git a/gcc/testsuite/g++.dg/lookup/name-clash15.C b/gcc/testsuite/g++.dg/lookup/name-clash15.C new file mode 100644 index 0000000..5c123bf --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/name-clash15.C @@ -0,0 +1,14 @@ +struct C { + static const int x = 24; +}; + +struct A +{ + struct B: C + { + enum { E = x }; + }; + + // OK, earlier x was found in a base, lookup didn't pass through A. + static const int x = 42; +}; diff --git a/gcc/testsuite/g++.dg/lookup/name-clash16.C b/gcc/testsuite/g++.dg/lookup/name-clash16.C new file mode 100644 index 0000000..250d614 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/name-clash16.C @@ -0,0 +1,13 @@ +typedef int T; + +struct A +{ + template <class T> + struct B + { + T t; + }; + + // OK, earlier T was found in template header, didn't look in A. + typedef float T; +}; diff --git a/gcc/testsuite/g++.dg/vect/pr105437.cc b/gcc/testsuite/g++.dg/vect/pr105437.cc new file mode 100644 index 0000000..b3b440d --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr105437.cc @@ -0,0 +1,24 @@ +// { dg-do compile } + +struct ControlClass +{ + virtual ~ControlClass(); + + int Width; + int Height; + unsigned IsToRepaint : 1; +}; + +struct SelectClass : ControlClass +{ + SelectClass(void); +}; + +int Non_Folded_Value(); + +SelectClass::SelectClass(void) +{ + int factor = Non_Folded_Value(); + Width = 32 << factor; + Height = 24 << factor; +} diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-37.C b/gcc/testsuite/g++.dg/warn/Wunused-var-37.C new file mode 100644 index 0000000..54e76ac --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-37.C @@ -0,0 +1,64 @@ +// Tangentially to PR c++/80351 +// { dg-do compile { target c++17 } } +// { dg-options "-Wunused-variable" } +#include <initializer_list> + +// Warnings: +static int int_s1 = 0; // { dg-warning "defined but not used" } +static int int_s2 = 0; // { dg-warning "defined but not used" } +inline static int int_is1 = 0; // { dg-warning "defined but not used" } +inline static int int_is2 = 0; // { dg-warning "defined but not used" } +// No warnings: +constexpr static int int_cs1 = 0; // { dg-bogus "defined but not used" } +constexpr static int int_cs2 = 0; // { dg-bogus "defined but not used" } +int int_1 = 0; // { dg-bogus "defined but not used" } +int int_2 = 0; // { dg-bogus "defined but not used" } +inline int int_i1 = 0; // { dg-bogus "defined but not used" } +inline int int_i2 = 0; // { dg-bogus "defined but not used" } +constexpr int int_c1 = 0; // { dg-bogus "defined but not used" } +constexpr int int_c2 = 0; // { dg-bogus "defined but not used" } + +// Warnings: +static auto int_as1 = 0; // { dg-warning "defined but not used" } +static auto int_as2 = 0; // { dg-warning "defined but not used" } +inline static auto int_ais1 = 0; // { dg-warning "defined but not used" } +inline static auto int_ais2 = 0; // { dg-warning "defined but not used" } +// No warnings: +constexpr static auto int_acs1 = 0; // { dg-bogus "defined but not used" } +constexpr static auto int_acs2 = 0; // { dg-bogus "defined but not used" } +auto int_a1 = 0; // { dg-bogus "defined but not used" } +auto int_a2 = 0; // { dg-bogus "defined but not used" } +inline auto int_ai1 = 0; // { dg-bogus "defined but not used" } +inline auto int_ai2 = 0; // { dg-bogus "defined but not used" } +constexpr auto int_ac1 = 0; // { dg-bogus "defined but not used" } +constexpr auto int_ac2 = 0; // { dg-bogus "defined but not used" } + +// Warnings: +static std::initializer_list<int> il_s1 = {0, 1}; // { dg-warning "defined but not used" } +static std::initializer_list<int> il_s2 = {0, 1}; // { dg-warning "defined but not used" } +inline static std::initializer_list<int> il_is1 = {0, 1}; // { dg-warning "defined but not used" } +inline static std::initializer_list<int> il_is2 = {0, 1}; // { dg-warning "defined but not used" } +// No warnings: +constexpr static std::initializer_list<int> il_cs1 = {0, 1}; // { dg-bogus "defined but not used" } +constexpr static std::initializer_list<int> il_cs2 = {0, 1}; // { dg-bogus "defined but not used" } +std::initializer_list<int> il_1 = {0, 1}; // { dg-bogus "defined but not used" } +std::initializer_list<int> il_2 = {0, 1}; // { dg-bogus "defined but not used" } +inline std::initializer_list<int> il_i1 = {0, 1}; // { dg-bogus "defined but not used" } +inline std::initializer_list<int> il_i2 = {0, 1}; // { dg-bogus "defined but not used" } +constexpr std::initializer_list<int> il_c1 = {0, 1}; // { dg-bogus "defined but not used" } +constexpr std::initializer_list<int> il_c2 = {0, 1}; // { dg-bogus "defined but not used" } + +// Warnings: +static auto il_as1 = {0, 1}; // { dg-warning "defined but not used" } +static auto il_as2 = {0, 1}; // { dg-warning "defined but not used" } +inline static auto il_ais1 = {0, 1}; // { dg-warning "defined but not used" } +inline static auto il_ais2 = {0, 1}; // { dg-warning "defined but not used" } +// No warnings: +constexpr static auto il_acs1 = {0, 1}; // { dg-bogus "defined but not used" } +constexpr static auto il_acs2 = {0, 1}; // { dg-bogus "defined but not used" } +auto il_a1 = {0, 1}; // { dg-bogus "defined but not used" } +auto il_a2 = {0, 1}; // { dg-bogus "defined but not used" } +inline auto il_ai1 = {0, 1}; // { dg-bogus "defined but not used" } +inline auto il_ai2 = {0, 1}; // { dg-bogus "defined but not used" } +constexpr auto il_ac1 = {0, 1}; // { dg-bogus "defined but not used" } +constexpr auto il_ac2 = {0, 1}; // { dg-bogus "defined but not used" } diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-38.C b/gcc/testsuite/g++.dg/warn/Wunused-var-38.C new file mode 100644 index 0000000..3d34bc8 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-38.C @@ -0,0 +1,16 @@ +// PR c++/80351 +// { dg-do compile { target c++11 } } +// { dg-options "-Wunused-variable" } +#include <initializer_list> + +constexpr auto int_1 = 1; // { dg-bogus "defined but not used" } +constexpr auto int_2 = 2; // { dg-bogus "defined but not used" } + +constexpr auto il_int_1 = {3, 3}; // { dg-bogus "defined but not used" "Triggered by PR80351" } +constexpr auto il_int_2 = {4, 4}; // { dg-bogus "defined but not used" "Not triggered by PR80351" } + +constexpr auto il_uint_1 = {5u, 5u}; // { dg-bogus "defined but not used" "Triggered by PR80351" } +constexpr auto il_uint_2 = {6u, 6u}; // { dg-bogus "defined but not used" "Not triggered by PR80351" } + +constexpr auto uint_1 = 7u; // { dg-bogus "defined but not used" } +constexpr auto uint_2 = 8u; // { dg-bogus "defined but not used" } diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-39.C b/gcc/testsuite/g++.dg/warn/Wunused-var-39.C new file mode 100644 index 0000000..d25a74c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-39.C @@ -0,0 +1,16 @@ +// PR c++/80351 +// { dg-do compile { target c++11 } } +// { dg-options "-Wunused-variable" } +#include <initializer_list> + +const auto int_1 = 1; // { dg-bogus "defined but not used" } +const auto int_2 = 2; // { dg-bogus "defined but not used" } + +const auto il_int_1 = {3, 3}; // { dg-bogus "defined but not used" "Triggered by PR80351" } +const auto il_int_2 = {4, 4}; // { dg-bogus "defined but not used" "Not triggered by PR80351" } + +const auto il_uint_1 = {5u, 5u}; // { dg-bogus "defined but not used" "Triggered by PR80351" } +const auto il_uint_2 = {6u, 6u}; // { dg-bogus "defined but not used" "Not triggered by PR80351" } + +const auto uint_1 = 7u; // { dg-bogus "defined but not used" } +const auto uint_2 = 8u; // { dg-bogus "defined but not used" } diff --git a/gcc/testsuite/gcc.dg/pr105415.c b/gcc/testsuite/gcc.dg/pr105415.c new file mode 100644 index 0000000..4603c0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105415.c @@ -0,0 +1,26 @@ +/* PR debug/105415 */ +/* { dg-do compile } */ +/* { dg-require-effective-target pthread } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fcompare-debug" } */ + +int m; +static int n; + +void +foo (void) +{ + int s = 0; + + while (m < 1) + { + s += n; + ++m; + } +} + +void +bar (int *arr, int i) +{ + while (i < 1) + arr[i++] = 1; +} diff --git a/gcc/testsuite/gcc.dg/pr105461.c b/gcc/testsuite/gcc.dg/pr105461.c new file mode 100644 index 0000000..1e6743c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105461.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fassociative-math -fsignaling-nans -fvar-tracking -w" } */ + +int +bar (float *x, int y) +{ + *x = y; + + return *x; +} + +__attribute__ ((optimize ("O2"))) void +foo (float *x, int y) +{ + int a = bar (x, y); +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c new file mode 100644 index 0000000..78905a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_cond_mixed } */ + +void foo (int *c, float *x, float *y) +{ + c[0] = x[0] < y[0]; + c[1] = y[1] > x[1]; + c[2] = x[2] < y[2]; + c[3] = x[3] < y[3]; +} + +/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c index 72b4930..c57f065 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c @@ -46,5 +46,5 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 1 "vect" { target { ! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "unsupported unaligned access" 1 "vect" { target { ! vect_hw_misalign } } } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_hw_misalign } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S b/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S index b4a4a14..db08f52 100644 --- a/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S +++ b/gcc/testsuite/gcc.target/i386/iamcu/asm-support.S @@ -300,3 +300,4 @@ iamcu_noprintf: .align 4 .LCiamcu_noprintf1: .long 1132527616 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S index 7a8ed03..2f8d3a09 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S @@ -82,3 +82,4 @@ snapshot_ret: .comm xmm_regs,256,32 .comm x87_regs,128,32 .comm volatile_var,8,8 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/avx/asm-support.S index 73a5919..77b3480 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/avx/asm-support.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/avx/asm-support.S @@ -79,3 +79,4 @@ snapshot_ret: .comm ymm_regs,512,32 .comm x87_regs,128,32 .comm volatile_var,8,8 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S index 0ef8287..2e3306c 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/avx512f/asm-support.S @@ -95,3 +95,4 @@ snapshot_ret: .comm zmm_regs,2048,64 .comm x87_regs,128,32 .comm volatile_var,8,8 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/asm-support.S index 7849acd..0793acf 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/asm-support.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/asm-support.S @@ -79,3 +79,4 @@ snapshot_ret: .comm xmm_regs,256,32 .comm x87_regs,128,32 .comm volatile_var,8,8 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m256h/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m256h/asm-support.S index 73a5919..77b3480 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m256h/asm-support.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m256h/asm-support.S @@ -79,3 +79,4 @@ snapshot_ret: .comm ymm_regs,512,32 .comm x87_regs,128,32 .comm volatile_var,8,8 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m512h/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m512h/asm-support.S index 0ef8287..2e3306c 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m512h/asm-support.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/avx512fp16/m512h/asm-support.S @@ -95,3 +95,4 @@ snapshot_ret: .comm zmm_regs,2048,64 .comm x87_regs,128,32 .comm volatile_var,8,8 + .section .note.GNU-stack,"",@progbits diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S index 7b891a1..f5dff4c 100644 --- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S +++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/do-test.S @@ -30,6 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifdef __ELF__ # define FN_TYPE(fn) .type fn,@function # define FN_SIZE(fn) .size fn,.-fn + .section .note.GNU-stack,"",@progbits #else # define FN_TYPE(fn) # define FN_SIZE(fn) diff --git a/gcc/tree-core.h b/gcc/tree-core.h index f1c2b64..07e76e6 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1563,9 +1563,7 @@ enum omp_clause_linear_kind struct GTY(()) tree_exp { struct tree_typed typed; location_t locus; - tree GTY ((special ("tree_exp"), - desc ("TREE_CODE ((tree) &%0)"))) - operands[1]; + tree GTY ((length ("TREE_OPERAND_LENGTH ((tree)&%h)"))) operands[1]; }; /* Immediate use linking structure. This structure is used for maintaining diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index 4415726..b53d7aa 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -3420,12 +3420,15 @@ expression_expensive_p (tree expr, hash_map<tree, uint64_t> &cache, break; return true; } + break; + default: + if (cfn == CFN_LAST + || !is_inexpensive_builtin (get_callee_fndecl (expr))) + return true; break; } - if (!is_inexpensive_builtin (get_callee_fndecl (expr))) - return true; FOR_EACH_CALL_EXPR_ARG (arg, iter, expr) if (expression_expensive_p (arg, cache, op_cost)) return true; diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index 4a0cf2e..89b0517 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -220,8 +220,7 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit) /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was set via a widening type conversion, then we may be able to record additional equivalences. */ - case NOP_EXPR: - case CONVERT_EXPR: + CASE_CONVERT: { tree rhs = gimple_assign_rhs1 (def_stmt); tree rhs_type = TREE_TYPE (rhs); diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index c957597..05536cd 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -395,8 +395,17 @@ set_range_info (tree name, enum value_range_kind range_type, { gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); - /* A range of the entire domain is really no range at all. */ tree type = TREE_TYPE (name); + if (range_type == VR_VARYING) + { + /* SSA_NAME_RANGE_TYPE can only hold a VR_RANGE or + VR_ANTI_RANGE. Denormalize VR_VARYING to VR_RANGE. */ + range_type = VR_RANGE; + gcc_checking_assert (min == wi::min_value (type)); + gcc_checking_assert (max == wi::max_value (type)); + } + + /* A range of the entire domain is really no range at all. */ if (min == wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)) && max == wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type))) { diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc index 8b7227e..e5bd9dc 100644 --- a/gcc/tree-vect-generic.cc +++ b/gcc/tree-vect-generic.cc @@ -1122,6 +1122,9 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) tree atype = build_nonstandard_integer_type (prec, 1); a = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, atype, a); } + else if (!a_is_comparison + && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a))) + comp_width = vector_element_bits_tree (TREE_TYPE (a)); int nunits = nunits_for_known_piecewise_op (type); vec_alloc (v, nunits); @@ -1148,7 +1151,7 @@ expand_vector_condition (gimple_stmt_iterator *gsi, bitmap dce_ssa_names) build_zero_cst (TREE_TYPE (a))); } else - aa = tree_vec_extract (gsi, cond_type, a, width, index); + aa = tree_vec_extract (gsi, cond_type, a, comp_width, comp_index); result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc); if (!CONSTANT_CLASS_P (result)) constant_p = false; diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 805dd7e..2685bc1 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -462,6 +462,7 @@ static const int cond_expr_maps[3][5] = { static const int arg1_map[] = { 1, 1 }; static const int arg2_map[] = { 1, 2 }; static const int arg1_arg4_map[] = { 2, 1, 4 }; +static const int op1_op0_map[] = { 2, 1, 0 }; /* For most SLP statements, there is a one-to-one mapping between gimple arguments and child nodes. If that is not true for STMT, @@ -482,6 +483,9 @@ vect_get_operand_map (const gimple *stmt, unsigned char swap = 0) if (gimple_assign_rhs_code (assign) == COND_EXPR && COMPARISON_CLASS_P (gimple_assign_rhs1 (assign))) return cond_expr_maps[swap]; + if (TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison + && swap) + return op1_op0_map; } gcc_assert (!swap); if (auto call = dyn_cast<const gcall *> (stmt)) @@ -1116,6 +1120,12 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, && (alt_stmt_code == PLUS_EXPR || alt_stmt_code == MINUS_EXPR) && rhs_code == alt_stmt_code) + && !(first_stmt_code.is_tree_code () + && rhs_code.is_tree_code () + && (TREE_CODE_CLASS (tree_code (first_stmt_code)) + == tcc_comparison) + && (swap_tree_comparison (tree_code (first_stmt_code)) + == tree_code (rhs_code))) && !(STMT_VINFO_GROUPED_ACCESS (stmt_info) && (first_stmt_code == ARRAY_REF || first_stmt_code == BIT_FIELD_REF @@ -1313,6 +1323,12 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, continue; } } + + if (rhs_code.is_tree_code () + && TREE_CODE_CLASS ((tree_code)rhs_code) == tcc_comparison + && (swap_tree_comparison ((tree_code)first_stmt_code) + == (tree_code)rhs_code)) + swap[i] = 1; } matches[i] = true; @@ -1326,7 +1342,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, with the permute we are going to use. */ if (alt_stmt_code != ERROR_MARK && (!alt_stmt_code.is_tree_code () - || TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_reference)) + || (TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_reference + && TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_comparison))) { *two_operators = true; } @@ -7302,6 +7319,13 @@ vect_schedule_slp_node (vec_info *vinfo, gcc_assert (seen_vector_def); si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]); } + else if (is_ctrl_altering_stmt (last_stmt)) + { + /* We split regions to vectorize at control altering stmts + with a definition so this must be an external which + we can insert at the start of the region. */ + si = gsi_after_labels (as_a <bb_vec_info> (vinfo)->bbs[0]); + } else if (is_a <bb_vec_info> (vinfo) && gimple_bb (last_stmt) != gimple_bb (stmt_info->stmt) && gimple_could_trap_p (stmt_info->stmt)) diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index f597666..5141ce5 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,7 @@ +2022-05-02 Martin Liska <mliska@suse.cz> + + * libgcov-driver.c: Add ATTRIBUTE_UNUSED. + 2022-04-28 Sebastian Huber <sebastian.huber@embedded-brains.de> * libgcov-util.c (ftw_read_file): Improve notice using xstrerror(). diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index d4517d2..aba62d5 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -413,6 +413,7 @@ dump_counter (gcov_type counter, /* Dump the STRING using the DUMP handler called with ARG. */ static inline void +ATTRIBUTE_UNUSED dump_string (const char *string, void (*dump_fn) (const void *, unsigned, void *), void *arg) diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map index 2ac5809..608a54c 100644 --- a/libgomp/libgomp.map +++ b/libgomp/libgomp.map @@ -226,6 +226,11 @@ OMP_5.1 { omp_get_teams_thread_limit_; } OMP_5.0.2; +OMP_5.1.1 { + global: + omp_get_mapped_ptr; +} OMP_5.1; + GOMP_1.0 { global: GOMP_atomic_end; diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index c10d0cb..38e0337 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -314,7 +314,7 @@ The OpenMP 4.5 specification is fully supported. @item @code{omp_target_is_accessible} runtime routine @tab N @tab @item @code{omp_target_memcpy_async} and @code{omp_target_memcpy_rect_async} runtime routines @tab N @tab -@item @code{omp_get_mapped_ptr} runtime routine @tab N @tab +@item @code{omp_get_mapped_ptr} runtime routine @tab Y @tab @item @code{omp_calloc}, @code{omp_realloc}, @code{omp_aligned_alloc} and @code{omp_aligned_calloc} runtime routines @tab Y @tab @item @code{omp_alloctrait_key_t} enum: @code{omp_atv_serialized} added, diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in index 89c5d65..18d0152 100644 --- a/libgomp/omp.h.in +++ b/libgomp/omp.h.in @@ -282,6 +282,7 @@ extern int omp_target_memcpy_rect (void *, const void *, __SIZE_TYPE__, int, extern int omp_target_associate_ptr (const void *, const void *, __SIZE_TYPE__, __SIZE_TYPE__, int) __GOMP_NOTHROW; extern int omp_target_disassociate_ptr (const void *, int) __GOMP_NOTHROW; +extern void *omp_get_mapped_ptr (const void *, int) __GOMP_NOTHROW; extern void omp_set_affinity_format (const char *) __GOMP_NOTHROW; extern __SIZE_TYPE__ omp_get_affinity_format (char *, __SIZE_TYPE__) diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in index daf40dc..506f15c 100644 --- a/libgomp/omp_lib.f90.in +++ b/libgomp/omp_lib.f90.in @@ -835,6 +835,15 @@ end function omp_target_disassociate_ptr end interface + interface + function omp_get_mapped_ptr (ptr, device_num) bind(c) + use, intrinsic :: iso_c_binding, only : c_ptr, c_int + type(c_ptr) :: omp_get_mapped_ptr + type(c_ptr), value :: ptr + integer(c_int), value :: device_num + end function omp_get_mapped_ptr + end interface + #if _OPENMP >= 201811 !GCC$ ATTRIBUTES DEPRECATED :: omp_get_nested, omp_set_nested #endif diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in index ff857a4..0f48510 100644 --- a/libgomp/omp_lib.h.in +++ b/libgomp/omp_lib.h.in @@ -416,3 +416,12 @@ integer(c_int), value :: device_num end function omp_target_disassociate_ptr end interface + + interface + function omp_get_mapped_ptr (ptr, device_num) bind(c) + use, intrinsic :: iso_c_binding, only : c_ptr, c_int + type(c_ptr) :: omp_get_mapped_ptr + type(c_ptr), value :: ptr + integer(c_int), value :: device_num + end function omp_get_mapped_ptr + end interface diff --git a/libgomp/target.c b/libgomp/target.c index 9017458..86930ea 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -3665,6 +3665,44 @@ omp_target_disassociate_ptr (const void *ptr, int device_num) return ret; } +void * +omp_get_mapped_ptr (const void *ptr, int device_num) +{ + if (device_num < 0 || device_num > gomp_get_num_devices ()) + return NULL; + + if (device_num == omp_get_initial_device ()) + return (void *) ptr; + + struct gomp_device_descr *devicep = resolve_device (device_num); + if (devicep == NULL) + return NULL; + + if (!(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400) + || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM) + return (void *) ptr; + + gomp_mutex_lock (&devicep->lock); + + struct splay_tree_s *mem_map = &devicep->mem_map; + struct splay_tree_key_s cur_node; + void *ret = NULL; + + cur_node.host_start = (uintptr_t) ptr; + cur_node.host_end = cur_node.host_start; + splay_tree_key n = gomp_map_0len_lookup (mem_map, &cur_node); + + if (n) + { + uintptr_t offset = cur_node.host_start - n->host_start; + ret = (void *) (n->tgt->tgt_start + n->tgt_offset + offset); + } + + gomp_mutex_unlock (&devicep->lock); + + return ret; +} + int omp_pause_resource (omp_pause_resource_t kind, int device_num) { diff --git a/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-1.c b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-1.c new file mode 100644 index 0000000..97a60ca --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-1.c @@ -0,0 +1,41 @@ +#include <omp.h> +#include <stdlib.h> + +int +main () +{ + int d = omp_get_default_device (); + int id = omp_get_initial_device (); + void *p , *q; + + if (d < 0 || d >= omp_get_num_devices ()) + d = id; + + p = omp_target_alloc (sizeof (int), d); + if (p == NULL) + return 0; + + if (omp_target_associate_ptr (q, p, sizeof (int), 0, d) != 0) + return 0; + + if (omp_get_mapped_ptr (q, -1) != NULL) + abort (); + + if (omp_get_mapped_ptr (q, omp_get_num_devices () + 1) != NULL) + abort (); + + if (omp_get_mapped_ptr (q, id) != q) + abort (); + + if (omp_get_mapped_ptr (q, d) != p) + abort (); + + if (omp_target_disassociate_ptr (q, d) != 0) + abort (); + + if (omp_get_mapped_ptr (q, d) != NULL) + abort (); + + omp_target_free (p, d); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-2.c b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-2.c new file mode 100644 index 0000000..194dade --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-2.c @@ -0,0 +1,106 @@ +#include <omp.h> +#include <stdlib.h> +#include <stdint.h> + +int +main () +{ + int d = omp_get_default_device (); + int id = omp_get_initial_device (); + int a = 42; + int b[] = { 24, 42 }; + int c[] = { 47, 11 }; + int e[128]; + int *q = &a; + void *p1 = NULL, *p2 = NULL, *p3 = NULL; + void *devptrs[128]; + + if (d < 0 || d >= omp_get_num_devices ()) + d = id; + + for (int i = 0; i < 128; i++) + e[i] = i; + + #pragma omp target data map(alloc: a, b, c[1], e[32:64]) device(d) + { + #pragma omp target map(from: p1, p2, p3, devptrs) map(alloc: a, b, c[1], e[32:64]) device(d) + { + p1 = &a; + p2 = &b; + p3 = &c[1]; + for (int i = 32; i < 96; i++) + devptrs[i] = &e[i]; + } + + if (omp_get_mapped_ptr (&a, d) != (d == id ? &a : p1) + || omp_get_mapped_ptr (q, d) != (d == id ? q : p1) + || omp_get_mapped_ptr (b, d) != (d == id ? b : p2) + || omp_get_mapped_ptr (&b[0], d) != (d == id ? &b[0] : p2) + || omp_get_mapped_ptr (&c[1], d) != (d == id ? &c[1] : p3) + || omp_get_mapped_ptr (&c[0], d) != (d == id ? &c[0] : NULL)) + abort (); + + for (int i = 0; i < 32; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : NULL)) + abort (); + for (int i = 32; i < 96; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : devptrs[i])) + abort (); + for (int i = 96; i < 128; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : NULL)) + abort (); + } + + if (omp_get_mapped_ptr (&a, d) != (d == id ? &a : NULL) + || omp_get_mapped_ptr (q, d) != (d == id ? q : NULL) + || omp_get_mapped_ptr (b, d) != (d == id ? b : NULL) + || omp_get_mapped_ptr (&b[0], d) != (d == id ? &b[0] : NULL) + || omp_get_mapped_ptr (&c[1], d) != (d == id ? &c[1] : NULL) + || omp_get_mapped_ptr (&c[0], d) != (d == id ? &c[0] : NULL)) + abort (); + for (int i = 0; i < 128; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : NULL)) + abort (); + + #pragma omp target enter data map (alloc: a, b, c[1], e[32:64]) device (d) + #pragma omp target map(from: p1, p2, p3, devptrs) map(alloc: a, b, c[1], e[32:64]) device(d) + { + p1 = &a; + p2 = &b; + p3 = &c[1]; + for (int i = 32; i < 96; i++) + devptrs[i] = &e[i]; + } + + if (omp_get_mapped_ptr (&a, d) != (d == id ? &a : p1) + || omp_get_mapped_ptr (q, d) != (d == id ? q : p1) + || omp_get_mapped_ptr (b, d) != (d == id ? b : p2) + || omp_get_mapped_ptr (&b[0], d) != (d == id ? &b[0] : p2) + || omp_get_mapped_ptr (&c[1], d) != (d == id ? &c[1] : p3) + || omp_get_mapped_ptr (&c[0], d) != (d == id ? &c[0] : NULL)) + abort (); + for (int i = 0; i < 32; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : NULL)) + abort (); + for (int i = 32; i < 96; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : devptrs[i])) + abort (); + for (int i = 96; i < 128; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : NULL)) + abort (); + + #pragma omp target exit data map (delete: a, b, c[1], e[32:64]) device (d) + + if (omp_get_mapped_ptr (&a, d) != (d == id ? &a : NULL) + || omp_get_mapped_ptr (q, d) != (d == id ? q : NULL) + || omp_get_mapped_ptr (b, d) != (d == id ? b : NULL) + || omp_get_mapped_ptr (&b[0], d) != (d == id ? &b[0] : NULL) + || omp_get_mapped_ptr (&c[1], d) != (d == id ? &c[1] : NULL) + || omp_get_mapped_ptr (&c[0], d) != (d == id ? &c[0] : NULL)) + abort (); + for (int i = 0; i < 128; i++) + if (omp_get_mapped_ptr (&e[i], d) != (d == id ? &e[i] : NULL)) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-3.c b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-3.c new file mode 100644 index 0000000..747ef75 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-3.c @@ -0,0 +1,51 @@ +#include <omp.h> +#include <stdlib.h> + +int +main () +{ + int d = omp_get_default_device (); + int id = omp_get_initial_device (); + int a[0]; + int b[] = { 24, 42 }; + void *p1 = NULL, *p2 = NULL; + + if (d < 0 || d >= omp_get_num_devices ()) + d = id; + + void *p = omp_target_alloc (sizeof (int), d); + if (p == NULL) + return 0; + + if (omp_target_associate_ptr (a, p, sizeof (int), 0, d) != 0) + return 0; + + if (omp_get_mapped_ptr (a, d) != (d == id ? a : p)) + abort (); + + if (omp_target_disassociate_ptr (a, d) != 0) + abort (); + + if (omp_get_mapped_ptr (a, d) != (d == id ? a : NULL)) + abort (); + + #pragma omp target data map(alloc: a, b[1:0]) device(d) + { + #pragma omp target map(from: p1, p2) map(alloc: a, b[1:0]) device(d) + { + p1 = &a; + p2 = &b[1]; + } + + /* This is probably expected to be p1/p2 instead of NULL. Zero-length arrays + as list items of the map clause are currently not inserted into the mem + map ?! However by returning NULL, omp_get_mapped_ptr is consistent with + omp_target_is_present. */ + if (omp_get_mapped_ptr (a, d) != NULL + || omp_get_mapped_ptr (&b[1], d) != NULL) + abort (); + } + + omp_target_free (p, d); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-4.c b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-4.c new file mode 100644 index 0000000..6f4bd62 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/get-mapped-ptr-4.c @@ -0,0 +1,49 @@ +#include <omp.h> +#include <stdlib.h> + +int +main () +{ + int d = omp_get_default_device (); + int id = omp_get_initial_device (); + struct s_t { int m1; char m2; } s; + void *p1 = NULL, *p2 = NULL; + + if (d < 0 || d >= omp_get_num_devices ()) + d = id; + + #pragma omp target data map(alloc: s, s.m2) device(d) + { + #pragma omp target map(from: p1, p2) map(alloc: s, s.m2) device(d) + { + p1 = &s; + p2 = &s.m2; + } + if (omp_get_mapped_ptr (&s, d) != (d == id ? &s : p1) + || omp_get_mapped_ptr (&s.m2, d) != (d == id ? &s.m2 : p2)) + abort (); + } + + if (omp_get_mapped_ptr (&s, d) != (d == id ? &s : NULL) + || omp_get_mapped_ptr (&s.m2, d) != (d == id ? &s.m2 : NULL)) + abort (); + + #pragma omp target enter data map(alloc: s, s.m2) device (d) + #pragma omp target map(from: p1, p2) map(alloc: s, s.m2) device(d) + { + p1 = &s; + p2 = &s.m2; + } + + if (omp_get_mapped_ptr (&s, d) != (d == id ? &s : p1) + || omp_get_mapped_ptr (&s.m2, d) != (d == id ? &s.m2 : p2)) + abort (); + + #pragma omp target exit data map (delete: s, s.m2) device (d) + + if (omp_get_mapped_ptr (&s, d) != (d == id ? &s : NULL) + || omp_get_mapped_ptr (&s.m2, d) != (d == id ? &s.m2 : NULL)) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-1.f90 b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-1.f90 new file mode 100644 index 0000000..de05179 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-1.f90 @@ -0,0 +1,43 @@ +program main + use omp_lib + use iso_c_binding + implicit none (external, type) + integer :: d, id + type(c_ptr) :: p + integer, target :: q + + d = omp_get_default_device () + id = omp_get_initial_device () + + if (d < 0 .or. d >= omp_get_num_devices ()) & + d = id + + p = omp_target_alloc (c_sizeof (q), d) + if (.not. c_associated (p)) & + stop 0 ! okay + + if (omp_target_associate_ptr (c_loc (q), p, c_sizeof (q), & + 0_c_size_t, d) == 0) then + + if(c_associated (omp_get_mapped_ptr (c_loc (q), -1))) & + stop 1 + + if(c_associated (omp_get_mapped_ptr (c_loc (q), & + omp_get_num_devices () + 1))) & + stop 2 + + if(.not. c_associated (omp_get_mapped_ptr (c_loc (q), id), c_loc (q))) & + stop 3 + + if(.not. c_associated (omp_get_mapped_ptr (c_loc (q), d), p)) & + stop 4 + + if (omp_target_disassociate_ptr (c_loc (q), d) /= 0) & + stop 5 + + if(c_associated (omp_get_mapped_ptr (c_loc (q), d))) & + stop 6 + end if + + call omp_target_free (p, d) +end program main diff --git a/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-2.f90 b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-2.f90 new file mode 100644 index 0000000..66a0b88 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-2.f90 @@ -0,0 +1,175 @@ +program main + use omp_lib + use iso_c_binding + implicit none (external, type) + integer :: d, id, i, j + integer, target :: a, b(1:2), c(1:2), e(0:127) + type(c_ptr) :: p1, p2, p3, q, devptrs(0:63) + + a = 42; + q = c_loc (a); + e = [(i, i = 0, 127)] + + d = omp_get_default_device () + id = omp_get_initial_device () + + if (d < 0 .or. d >= omp_get_num_devices ()) & + d = id + + if (d /= id) then + !$omp target data map(alloc: a, b, c(2), e(32:95)) device(d) + !$omp target map(from: p1, p2, p3, devptrs) map(alloc: a, b, c(2), e(32:95)) device(d) + p1 = c_loc (a); + p2 = c_loc (b); + p3 = c_loc (c(2)) + devptrs = [(c_loc (e(i)), i = 32, 95)] + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), p1) & + .or. .not. c_associated (omp_get_mapped_ptr (q, d), p1) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b), d), p2) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d), p2) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d), p3) & + .or. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d))) & + stop 0 + + do j = 0, 31 + if (c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 1 + end do + do j = 32, 95 + if (.not. c_associated (omp_get_mapped_ptr (c_loc (e(j)), d), devptrs(j-32))) & + stop 2 + end do + do j = 96, 128 + if (c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 3 + end do + !$omp end target data + + if (c_associated (omp_get_mapped_ptr (c_loc (a), d)) & + .or. c_associated (omp_get_mapped_ptr (q, d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (b), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d))) & + stop 4 + do j = 0, 127 + if (c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 5 + end do + + !$omp target enter data map (alloc: a, b, c(2), e(32:95)) device (d) + !$omp target map(from: p1, p2, p3, devptrs) map(alloc: a, b, c(2), e(32:95)) device(d) + p1 = c_loc (a); + p2 = c_loc (b); + p3 = c_loc (c(2)) + devptrs = [(c_loc (e(i)), i = 32, 95)] + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), p1) & + .or. .not. c_associated (omp_get_mapped_ptr (q, d), p1) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b), d), p2) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d), p3) & + .or. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d))) & + stop 6 + + do j = 0, 31 + if (c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 7 + end do + do j = 32, 95 + if (.not. c_associated (omp_get_mapped_ptr (c_loc (e(j)), d), devptrs(j-32))) & + stop 8 + end do + do j = 96, 128 + if (c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 9 + end do + !$omp target exit data map (delete: a, b, c(2), e(32:95)) device (d) + + if (c_associated (omp_get_mapped_ptr (c_loc (a), d)) & + .or. c_associated (omp_get_mapped_ptr (q, d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (b), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d))) & + stop 10 + do j = 0, 127 + if (c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 11 + end do + + else ! d == id + + !$omp target data map(alloc: a, b, c(2), e(32:95)) device(d) + !$omp target map(from: p1, p2, p3, devptrs) map(alloc: a, b, c(2), e(32:95)) device(d) + p1 = c_loc (a); + p2 = c_loc (b); + p3 = c_loc (c(2)) + devptrs = [(c_loc (e(i)), i = 32, 95)] + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), c_loc (a)) & + .or. .not. c_associated (omp_get_mapped_ptr (q, d), q) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b), d), c_loc (b)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d), c_loc (b(1))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d), c_loc (c(2))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d), c_loc (c(1)))) & + stop 12 + + do j = 0, 127 + if (.not. c_associated (omp_get_mapped_ptr (c_loc (e(j)), d), c_loc (e(j)))) & + stop 13 + end do + !$omp end target data + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), c_loc (a)) & + .or. .not. c_associated (omp_get_mapped_ptr (q, d), q) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b), d), c_loc (b)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d), c_loc (b(1))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d), c_loc (c(2))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d), c_loc (c(1)))) & + stop 14 + do j = 0, 127 + if (.not. c_associated (omp_get_mapped_ptr (c_loc (e(j)), d))) & + stop 15 + end do + + !$omp target enter data map (alloc: a, b, c(2), e(32:95)) device (d) + !$omp target map(from: p1, p2, p3, devptrs) map(alloc: a, b, c(2), e(32:95)) device(d) + p1 = c_loc (a); + p2 = c_loc (b); + p3 = c_loc (c(2)) + devptrs = [(c_loc (e(i)), i = 32, 95)] + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), c_loc (a)) & + .or. .not. c_associated (omp_get_mapped_ptr (q, d), q) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b), d), c_loc (b)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d), c_loc (b(1))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d), c_loc (c(2))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d), c_loc (c(1)))) & + stop 16 + + do j = 0, 127 + if (.not. c_associated (omp_get_mapped_ptr (c_loc (e(j)), d), c_loc (e(j)))) & + stop 17 + end do + !$omp target exit data map (delete: a, b, c(2), e(32:95)) device (d) + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), c_loc (a)) & + .or. .not. c_associated (omp_get_mapped_ptr (q, d), q) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b), d), c_loc (b)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (b(1)), d), c_loc (b(1))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(2)), d), c_loc (c(2))) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (c(1)), d), c_loc (c(1)))) & + stop 18 + + do j = 0, 127 + if (.not. c_associated (omp_get_mapped_ptr (c_loc (e(j)), d), c_loc (e(j)))) & + stop 19 + end do + end if + +end program main diff --git a/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-3.f90 b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-3.f90 new file mode 100644 index 0000000..8e7ccac --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-3.f90 @@ -0,0 +1,48 @@ +program main + use omp_lib + use iso_c_binding + implicit none (external, type) + integer :: d, id + type(c_ptr) :: p, p1, p2 + integer, target :: a(1:0), b(1:2) + + d = omp_get_default_device () + id = omp_get_initial_device () + + if (d < 0 .or. d >= omp_get_num_devices ()) & + d = id + + p = omp_target_alloc (c_sizeof (c_int), d) + if (.not. c_associated (p)) & + stop 0 ! okay + + if (omp_target_associate_ptr (c_loc (a), p, c_sizeof (c_int), & + 0_c_size_t, d) == 0) then + + if(.not. c_associated (omp_get_mapped_ptr (c_loc (a), d), p)) & + stop 1 + + if (omp_target_disassociate_ptr (c_loc (a), d) /= 0) & + stop 2 + + if(c_associated (omp_get_mapped_ptr (c_loc (a), d))) & + stop 3 + + !$omp target data map(alloc: a) device(d) + !$omp target map(from: p1) map(alloc: a) device(d) + p1 = c_loc (a); + !$omp end target + if (c_associated (omp_get_mapped_ptr (c_loc (a), d))) & + stop 4 + !$omp end target data + + !$omp target data map(alloc: b(1:0)) device(d) + !$omp target map(from: p2) map(alloc: b(1:0)) device(d) + p2 = c_loc (b(1)); + !$omp end target + if (c_associated (omp_get_mapped_ptr (c_loc (b(1)), d))) & + stop 5 + !$omp end target data + end if + call omp_target_free (p, d) +end program main diff --git a/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-4.f90 b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-4.f90 new file mode 100644 index 0000000..4300a55 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/get-mapped-ptr-4.f90 @@ -0,0 +1,84 @@ +program main + use omp_lib + use iso_c_binding + implicit none (external, type) + integer :: d, id + type(c_ptr) :: p1, p2 + + type t + integer :: m1, m2 + end type t + type(t), target :: s + + d = omp_get_default_device () + id = omp_get_initial_device () + + if (d < 0 .or. d >= omp_get_num_devices ()) & + d = id + + if (d /= id) then + !$omp target data map(alloc: s, s%m2) device(d) + !$omp target map(from: p1, p2) map(alloc: s, s%m2) device(d) + p1 = c_loc (s); + p2 = c_loc (s%m2); + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (s), d), p1) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d), p2)) & + stop 0 + !$omp end target data + + if (c_associated (omp_get_mapped_ptr (c_loc (s), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d))) & + stop 1 + + !$omp target enter data map (alloc: s, s%m2) device (d) + !$omp target map(from: p1, p2) map(alloc: s, s%m2) device(d) + p1 = c_loc (s); + p2 = c_loc (s%m2); + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (s), d), p1) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d), p2)) & + stop 2 + !$omp target exit data map (delete: s, s%m2) device (d) + + if (c_associated (omp_get_mapped_ptr (c_loc (s), d)) & + .or. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d))) & + stop 3 + + else ! d == id + + !$omp target data map(alloc: s, s%m2) device(d) + !$omp target map(from: p1, p2) map(alloc: s, s%m2) device(d) + p1 = c_loc (s); + p2 = c_loc (s%m2); + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (s), d), c_loc (s)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d), c_loc (s%m2))) & + stop 4 + !$omp end target data + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (s), d), c_loc (s)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d), c_loc (s%m2))) & + stop 5 + + !$omp target enter data map (alloc: s, s%m2) device (d) + !$omp target map(from: p1, p2) map(alloc: s, s%m2) device(d) + p1 = c_loc (s); + p2 = c_loc (s%m2); + !$omp end target + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (s), d), c_loc (s)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d), c_loc (s%m2))) & + stop 6 + + !$omp target exit data map (delete: s, s%m2) device (d) + + if (.not. c_associated (omp_get_mapped_ptr (c_loc (s), d), c_loc (s)) & + .or. .not. c_associated (omp_get_mapped_ptr (c_loc (s%m2), d), c_loc (s%m2))) & + stop 7 + end if + +end program main diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c174262..6a9fcd3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,36 @@ +2022-05-02 Patrick Palka <ppalka@redhat.com> + + PR libstdc++/103911 + * src/c++17/floating_from_chars.cc (find_end_of_float): Accept + two delimeters for the exponent part in the form of a possibly + NULL string of length two. Don't use std::tolower. + (pattern): Adjust calls to find_end_of_float accordingly. + +2022-05-02 Patrick Palka <ppalka@redhat.com> + + PR libstdc++/105441 + * src/c++17/floating_from_chars.cc (__floating_from_chars_hex): + Also accept 'P' as the start of the exponent. + * testsuite/20_util/from_chars/7.cc: Add corresponding testcase. + +2022-04-29 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/105417 + * config/abi/post/powerpc64-linux-gnu/baseline_symbols.txt: + Regenerate. + * src/c++11/compatibility-ldbl-alt128.cc [_GLIBCXX_USE_DUAL_ABI]: + Define __gnu_ieee128::num_get<C>::_M_extract_int[abi:cxx11]<I> + symbols as aliases for corresponding symbols without abi-tag. + +2022-04-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * config/abi/post/i386-solaris/baseline_symbols.txt: Regenerate. + * config/abi/post/i386-solaris/amd64/baseline_symbols.txt: + Likewise. + * config/abi/post/sparc-solaris/baseline_symbols.txt: Likewise. + * config/abi/post/sparc-solaris/sparcv9/baseline_symbols.txt: + Likewise. + 2022-04-28 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/99290 diff --git a/libstdc++-v3/src/c++17/floating_from_chars.cc b/libstdc++-v3/src/c++17/floating_from_chars.cc index 13de1e3..5d2a931 100644 --- a/libstdc++-v3/src/c++17/floating_from_chars.cc +++ b/libstdc++-v3/src/c++17/floating_from_chars.cc @@ -40,7 +40,6 @@ #include <cmath> #include <cstdlib> #include <cstring> -#include <cctype> #include <locale.h> #include <bits/functexcept.h> #if _GLIBCXX_HAVE_XLOCALE_H @@ -142,10 +141,10 @@ namespace // Find initial portion of [first, last) containing a floating-point number. // The string `digits` is either `dec_digits` or `hex_digits` - // and `exp` is 'e' or 'p' or '\0'. + // and `exp` is "eE", "pP" or NULL. const char* find_end_of_float(const char* first, const char* last, const char* digits, - char exp) + const char *exp) { while (first < last && strchr(digits, *first) != nullptr) ++first; @@ -155,7 +154,7 @@ namespace while (first < last && strchr(digits, *first)) ++first; } - if (first < last && exp != 0 && std::tolower((unsigned char)*first) == exp) + if (first < last && exp != nullptr && (*first == exp[0] || *first == exp[1])) { ++first; if (first < last && (*first == '-' || *first == '+')) @@ -237,7 +236,7 @@ namespace if ((last - first + 2) > buffer_resource::guaranteed_capacity()) { - last = find_end_of_float(first + neg, last, digits, 'p'); + last = find_end_of_float(first + neg, last, digits, "pP"); #ifndef __cpp_exceptions if ((last - first + 2) > buffer_resource::guaranteed_capacity()) { @@ -261,7 +260,7 @@ namespace if ((last - first) > buffer_resource::guaranteed_capacity()) { last = find_end_of_float(first + neg, last, digits, - "e"[fmt == chars_format::fixed]); + fmt == chars_format::fixed ? nullptr : "eE"); #ifndef __cpp_exceptions if ((last - first) > buffer_resource::guaranteed_capacity()) { @@ -664,7 +663,7 @@ namespace // Parse the written exponent. int written_exponent = 0; - if (first != last && *first == 'p') + if (first != last && (*first == 'p' || *first == 'P')) { // Tentatively consume the 'p' and try to parse a decimal number. const char* const fallback_first = first; diff --git a/libstdc++-v3/testsuite/20_util/from_chars/7.cc b/libstdc++-v3/testsuite/20_util/from_chars/7.cc index 2a78c74..1aa9b23 100644 --- a/libstdc++-v3/testsuite/20_util/from_chars/7.cc +++ b/libstdc++-v3/testsuite/20_util/from_chars/7.cc @@ -96,6 +96,7 @@ constexpr testcase testcases[] = { { "1p-1", 4, {}, 0x1p-1 }, { "0", 1, {}, 0.0 }, { "A", 1, {}, 0xA }, + { "1.ABCDEFP+10", 12, {}, 0x1.ABCDEFP+10 }, { "-1", 2, {}, -1.0 }, { "-0", 2, {}, -0.0 }, { "42", 2, {}, 0x42p0 }, |