diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-09-22 06:29:20 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-09-22 06:29:20 -0700 |
commit | 795cffe109e28b248a54b8ee583cbae48368c2a7 (patch) | |
tree | 0c12b075c51c0d5097f26953835ae540d9f2f501 /gcc/fortran | |
parent | 9f62ed218fa656607740b386c0caa03e65dcd283 (diff) | |
parent | f35be1268c996d993ab0b4ff329734d467474445 (diff) | |
download | gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.zip gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.tar.gz gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.tar.bz2 |
Merge from trunk revision f35be1268c996d993ab0b4ff329734d467474445.
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 252 | ||||
-rw-r--r-- | gcc/fortran/decl.cc | 3 | ||||
-rw-r--r-- | gcc/fortran/dump-parse-tree.cc | 38 | ||||
-rw-r--r-- | gcc/fortran/expr.cc | 3 | ||||
-rw-r--r-- | gcc/fortran/f95-lang.cc | 23 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 13 | ||||
-rw-r--r-- | gcc/fortran/gfortran.texi | 13 | ||||
-rw-r--r-- | gcc/fortran/interface.cc | 11 | ||||
-rw-r--r-- | gcc/fortran/invoke.texi | 21 | ||||
-rw-r--r-- | gcc/fortran/lang.opt | 6 | ||||
-rw-r--r-- | gcc/fortran/libgfortran.h | 21 | ||||
-rw-r--r-- | gcc/fortran/match.cc | 24 | ||||
-rw-r--r-- | gcc/fortran/match.h | 6 | ||||
-rw-r--r-- | gcc/fortran/mathbuiltins.def | 1 | ||||
-rw-r--r-- | gcc/fortran/openmp.cc | 235 | ||||
-rw-r--r-- | gcc/fortran/options.cc | 7 | ||||
-rw-r--r-- | gcc/fortran/parse.cc | 5 | ||||
-rw-r--r-- | gcc/fortran/primary.cc | 14 | ||||
-rw-r--r-- | gcc/fortran/resolve.cc | 1 | ||||
-rw-r--r-- | gcc/fortran/scanner.cc | 8 | ||||
-rw-r--r-- | gcc/fortran/simplify.cc | 22 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.cc | 10 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.cc | 249 | ||||
-rw-r--r-- | gcc/fortran/trans-openmp.cc | 63 | ||||
-rw-r--r-- | gcc/fortran/trans-types.cc | 15 |
25 files changed, 867 insertions, 197 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index acd60ff..a53df93 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,255 @@ +2022-09-20 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/104143 + * interface.cc (compare_parameter): Permit scalar args to + 'type(*), dimension(*)'. + +2022-09-20 Harald Anlauf <anlauf@gmx.de> + + PR fortran/106986 + * simplify.cc (gfc_simplify_findloc): Do not try to simplify + intrinsic FINDLOC when the ARRAY argument has a NULL shape. + +2022-09-20 Harald Anlauf <anlauf@gmx.de> + + PR fortran/106985 + * expr.cc (gfc_simplify_expr): Avoid NULL pointer dereference. + +2022-09-20 José Rui Faustino de Sousa <jrfsousa@gmail.com> + + PR fortran/100132 + * trans-types.cc (create_fn_spec): Fix function attributes when + passing polymorphic pointers. + +2022-09-20 Martin Liska <mliska@suse.cz> + + PR fortran/106636 + * gfortran.texi: Add back link to ISO_VARYING_STRING. + +2022-09-20 Martin Liska <mliska@suse.cz> + + * gfortran.texi: Replace "the the" with "the". + +2022-09-20 Martin Liska <mliska@suse.cz> + + PR fortran/106636 + * gfortran.texi: Remove 2 dead links. + +2022-09-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + * libgfortran.h: Declare GFC_FPE_AWAY. + +2022-09-15 Harald Anlauf <anlauf@gmx.de> + + PR fortran/106857 + * simplify.cc (gfc_simplify_pack): Check for NULL pointer dereferences + while walking through constructors (error recovery). + +2022-09-15 Harald Anlauf <anlauf@gmx.de> + Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/104314 + * resolve.cc (deferred_op_assign): Do not try to generate temporary + for deferred character length assignment if types do not agree. + +2022-09-15 Richard Biener <rguenther@suse.de> + + * f95-lang.cc (gfc_init_decl_processing): Do not initialize + void_list_node. + +2022-09-14 Julian Brown <julian@codesourcery.com> + + * trans-openmp.cc (gfc_trans_omp_clauses): Don't create + GOMP_MAP_TO_PSET mappings for class metadata, nor GOMP_MAP_POINTER + mappings for POINTER_TYPE_P decls. + +2022-09-10 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/95644 + * f95-lang.cc (gfc_init_builtin_functions): Declare FMA + built-ins. + * mathbuiltins.def: Declare FMA built-ins. + * trans-intrinsic.cc (conv_intrinsic_ieee_fma): New function. + (conv_intrinsic_ieee_signbit): New function. + (gfc_build_intrinsic_lib_fndecls): Add cases for FMA and + SIGNBIT. + +2022-09-08 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/106670 + * scanner.cc (skip_fixed_omp_sentinel): Add -Wsurprising warning + for 'omx' sentinels with -fopenmp. + * invoke.texi (-Wsurprising): Document additional warning case. + +2022-09-06 Tobias Burnus <tobias@codesourcery.com> + + * openmp.cc (resolve_omp_clauses): Remove ordered/linear + check as it is handled now in the middle end. + +2022-09-05 Tobias Burnus <tobias@codesourcery.com> + + * dump-parse-tree.cc (show_omp_namelist, show_omp_clauses): Handle + omp_cur_iteration and distinguish doacross/depend. + * gfortran.h (enum gfc_omp_depend_doacross_op): Renamed from + gfc_omp_depend_op. + (enum gfc_omp_depend_doacross_op): Add OMP_DOACROSS_SINK_FIRST, + Rename OMP_DEPEND_SINK to OMP_DOACROSS_SINK. + (gfc_omp_namelist) Handle renaming, rename depend_op to + depend_doacross_op. + (struct gfc_omp_clauses): Add doacross_source. + * openmp.cc (gfc_match_omp_depend_sink): Renamed to ... + (gfc_match_omp_doacross_sink): ... this; handle omp_all_memory. + (enum omp_mask2): Add OMP_CLAUSE_DOACROSS. + (gfc_match_omp_clauses): Handle 'doacross' and syntax changes to + depend. + (gfc_match_omp_depobj): Simplify as sink/source are now impossible. + (gfc_match_omp_ordered_depend): Request OMP_CLAUSE_DOACROSS. + (resolve_omp_clauses): Update sink/source checks. + (gfc_resolve_omp_directive): Resolve EXEC_OMP_ORDERED clauses. + * parse.cc (decode_omp_directive): Handle 'ordered doacross'. + * trans-openmp.cc (gfc_trans_omp_clauses): Handle doacross. + (gfc_trans_omp_do): Fix OMP_FOR_ORIG_DECLS handling if 'ordered' + clause is present. + (gfc_trans_omp_depobj): Update for member name change. + +2022-09-04 José Rui Faustino de Sousa <jrfsousa@gmail.com> + + PR fortran/100136 + * trans-expr.cc (gfc_conv_procedure_call): Add handling of pointer + expressions. + +2022-09-03 José Rui Faustino de Sousa <jrfsousa@gmail.com> + + PR fortran/100245 + * trans-expr.cc (trans_class_assignment): Add if clause to handle + derived type in the LHS. + +2022-09-03 Jakub Jelinek <jakub@redhat.com> + + * trans-openmp.cc (gfc_trans_omp_clauses): Use + OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of + OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS + clause instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND + on it. + +2022-09-02 Harald Anlauf <anlauf@gmx.de> + Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/99349 + * decl.cc (match_data_constant): Avoid NULL pointer dereference. + +2022-08-26 Jakub Jelinek <jakub@redhat.com> + + PR fortran/106579 + * trans-intrinsic.cc: Include realmpfr.h. + (conv_intrinsic_ieee_value): New function. + (gfc_conv_ieee_arithmetic_function): Handle ieee_value. + +2022-08-26 Jakub Jelinek <jakub@redhat.com> + + PR fortran/106579 + * f95-lang.cc (gfc_init_builtin_functions): Initialize + BUILT_IN_FPCLASSIFY. + * libgfortran.h (IEEE_OTHER_VALUE, IEEE_SIGNALING_NAN, + IEEE_QUIET_NAN, IEEE_NEGATIVE_INF, IEEE_NEGATIVE_NORMAL, + IEEE_NEGATIVE_DENORMAL, IEEE_NEGATIVE_SUBNORMAL, + IEEE_NEGATIVE_ZERO, IEEE_POSITIVE_ZERO, IEEE_POSITIVE_DENORMAL, + IEEE_POSITIVE_SUBNORMAL, IEEE_POSITIVE_NORMAL, IEEE_POSITIVE_INF): + New enum. + * trans-intrinsic.cc (conv_intrinsic_ieee_class): New function. + (gfc_conv_ieee_arithmetic_function): Handle ieee_class. + +2022-08-26 Jakub Jelinek <jakub@redhat.com> + + * f95-lang.cc (gfc_init_builtin_functions): Initialize + BUILT_IN_ISSIGNALING. + +2022-08-25 Tobias Burnus <tobias@codesourcery.com> + + * parse.cc (parse_omp_structured_block): When parsing strictly + structured blocks, issue an error if the end-directive comes + before the 'end block'. + +2022-08-24 Harald Anlauf <anlauf@gmx.de> + + PR fortran/103694 + * simplify.cc (simplify_size): The size expression of an array cannot + be simplified if an error occurs while resolving the array spec. + +2022-08-22 Harald Anlauf <anlauf@gmx.de> + + PR fortran/106557 + * simplify.cc (gfc_simplify_ibclr): Ensure consistent results of + the simplification by dropping a redundant memory representation + of argument x. + (gfc_simplify_ibset): Likewise. + +2022-08-20 Jakub Jelinek <jakub@redhat.com> + + PR fortran/46539 + * lang.opt (static-libgfortran, static-libquadmath): Change Fortran + to Driver. + * options.cc (gfc_handle_option): Don't handle OPT_static_libgfortran + nor OPT_static_libquadmath here. + +2022-08-18 Harald Anlauf <anlauf@gmx.de> + + Revert: + 2022-07-31 Harald Anlauf <anlauf@gmx.de> + + PR fortran/77652 + * check.cc (gfc_check_associated): Make the rank check of POINTER + vs. TARGET match the allowed forms of pointer assignment for the + selected Fortran standard. + +2022-08-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + Jakub Jelinek <jakub@redhat.com> + + PR fortran/46539 + * lang.opt (static-libquadmath): New option. + * invoke.texi (-static-libquadmath): Document it. + * options.cc (gfc_handle_option): Error out if -static-libquadmath + is passed but we do not support it. + +2022-08-17 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/106566 + * openmp.cc (gfc_match_omp_clauses): Fix setting linear-step value + to 1 when not specified. + (gfc_match_omp_declare_simd): Accept module procedures. + +2022-08-16 Martin Liska <mliska@suse.cz> + + * gfortran.texi: Fix link destination to a valid URL. + +2022-07-31 Harald Anlauf <anlauf@gmx.de> + Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/92805 + * match.cc (gfc_match_small_literal_int): Make gobbling of leading + whitespace optional. + (gfc_match_name): Likewise. + (gfc_match_char): Likewise. + * match.h (gfc_match_small_literal_int): Adjust prototype. + (gfc_match_name): Likewise. + (gfc_match_char): Likewise. + * primary.cc (match_kind_param): Match small literal int or name + without gobbling whitespace. + (get_kind): Do not skip over blanks. + (match_string_constant): Likewise. + +2022-07-31 Harald Anlauf <anlauf@gmx.de> + + PR fortran/77652 + * check.cc (gfc_check_associated): Make the rank check of POINTER + vs. TARGET match the allowed forms of pointer assignment for the + selected Fortran standard. + +2022-07-29 Tobias Burnus <tobias@codesourcery.com> + + * openmp.cc (resolve_omp_clauses): Permit assumed-size arrays + in uniform clause. + 2022-07-26 Harald Anlauf <anlauf@gmx.de> PR fortran/103504 diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index b640051..0f9b2ce 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -423,7 +423,8 @@ match_data_constant (gfc_expr **result) data-pointer-initialization compatible (7.5.4.6) with the initial data target; the data statement object is initially associated with the target. */ - if ((*result)->symtree->n.sym->attr.save + if ((*result)->symtree + && (*result)->symtree->n.sym->attr.save && (*result)->symtree->n.sym->attr.target) return m; gfc_free_expr (*result); diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 5352008..40c690c 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1337,8 +1337,15 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) if (n->u2.ns != ns_iter) { if (n != n2) - fputs (list_type == OMP_LIST_AFFINITY - ? ") AFFINITY(" : ") DEPEND(", dumpfile); + { + fputs (") ", dumpfile); + if (list_type == OMP_LIST_AFFINITY) + fputs ("AFFINITY (", dumpfile); + else if (n->u.depend_doacross_op == OMP_DOACROSS_SINK_FIRST) + fputs ("DOACROSS (", dumpfile); + else + fputs ("DEPEND (", dumpfile); + } if (n->u2.ns) { fputs ("ITERATOR(", dumpfile); @@ -1374,7 +1381,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) default: break; } else if (list_type == OMP_LIST_DEPEND) - switch (n->u.depend_op) + switch (n->u.depend_doacross_op) { case OMP_DEPEND_IN: fputs ("in:", dumpfile); break; case OMP_DEPEND_OUT: fputs ("out:", dumpfile); break; @@ -1385,10 +1392,14 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) fputs ("mutexinoutset:", dumpfile); break; case OMP_DEPEND_SINK_FIRST: + case OMP_DOACROSS_SINK_FIRST: fputs ("sink:", dumpfile); while (1) { - fprintf (dumpfile, "%s", n->sym->name); + if (!n->sym) + fputs ("omp_cur_iteration", dumpfile); + else + fprintf (dumpfile, "%s", n->sym->name); if (n->expr) { fputc ('+', dumpfile); @@ -1396,9 +1407,13 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) } if (n->next == NULL) break; - else if (n->next->u.depend_op != OMP_DEPEND_SINK) + else if (n->next->u.depend_doacross_op != OMP_DOACROSS_SINK) { - fputs (") DEPEND(", dumpfile); + if (n->next->u.depend_doacross_op + == OMP_DOACROSS_SINK_FIRST) + fputs (") DOACROSS(", dumpfile); + else + fputs (") DEPEND(", dumpfile); break; } fputc (',', dumpfile); @@ -1674,7 +1689,14 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) case OMP_LIST_AFFINITY: type = "AFFINITY"; break; case OMP_LIST_ALIGNED: type = "ALIGNED"; break; case OMP_LIST_LINEAR: type = "LINEAR"; break; - case OMP_LIST_DEPEND: type = "DEPEND"; break; + case OMP_LIST_DEPEND: + if (omp_clauses->lists[list_type] + && (omp_clauses->lists[list_type]->u.depend_doacross_op + == OMP_DOACROSS_SINK_FIRST)) + type = "DOACROSS"; + else + type = "DEPEND"; + break; case OMP_LIST_MAP: type = "MAP"; break; case OMP_LIST_TO: type = "TO"; break; case OMP_LIST_FROM: type = "FROM"; break; @@ -1894,6 +1916,8 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) fputs (" DESTROY", dumpfile); if (omp_clauses->depend_source) fputs (" DEPEND(source)", dumpfile); + if (omp_clauses->doacross_source) + fputs (" DOACROSS(source:)", dumpfile); if (omp_clauses->capture) fputs (" CAPTURE", dumpfile); if (omp_clauses->depobj_update != OMP_DEPEND_UNSET) diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index be94c18..290ddf3 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -2287,7 +2287,8 @@ gfc_simplify_expr (gfc_expr *p, int type) initialization expression, or we want a subsection. */ if (p->symtree->n.sym->attr.flavor == FL_PARAMETER && (gfc_init_expr_flag || p->ref - || p->symtree->n.sym->value->expr_type != EXPR_ARRAY)) + || (p->symtree->n.sym->value + && p->symtree->n.sym->value->expr_type != EXPR_ARRAY))) { if (!simplify_parameter_variable (p, type)) return false; diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc index 319cf8f..a6750be 100644 --- a/gcc/fortran/f95-lang.cc +++ b/gcc/fortran/f95-lang.cc @@ -530,8 +530,6 @@ gfc_init_decl_processing (void) only use it for actual characters, not for INTEGER(1). */ build_common_tree_nodes (false); - void_list_node = build_tree_list (NULL_TREE, void_type_node); - /* Set up F95 type nodes. */ gfc_init_kinds (); gfc_init_types (); @@ -1013,10 +1011,13 @@ gfc_init_builtin_functions (void) "__builtin_isnan", ATTR_CONST_NOTHROW_LEAF_LIST); gfc_define_builtin ("__builtin_isnormal", ftype, BUILT_IN_ISNORMAL, "__builtin_isnormal", ATTR_CONST_NOTHROW_LEAF_LIST); + gfc_define_builtin ("__builtin_issignaling", ftype, BUILT_IN_ISSIGNALING, + "__builtin_issignaling", ATTR_CONST_NOTHROW_LEAF_LIST); gfc_define_builtin ("__builtin_signbit", ftype, BUILT_IN_SIGNBIT, "__builtin_signbit", ATTR_CONST_NOTHROW_LEAF_LIST); + gfc_define_builtin ("__builtin_fpclassify", ftype, BUILT_IN_FPCLASSIFY, + "__builtin_fpclassify", ATTR_CONST_NOTHROW_LEAF_LIST); - ftype = build_function_type (integer_type_node, NULL_TREE); gfc_define_builtin ("__builtin_isless", ftype, BUILT_IN_ISLESS, "__builtin_isless", ATTR_CONST_NOTHROW_LEAF_LIST); gfc_define_builtin ("__builtin_islessequal", ftype, BUILT_IN_ISLESSEQUAL, @@ -1278,6 +1279,22 @@ gfc_init_builtin_functions (void) "__builtin_assume_aligned", ATTR_CONST_NOTHROW_LEAF_LIST); + ftype = build_function_type_list (long_double_type_node, long_double_type_node, + long_double_type_node, long_double_type_node, + NULL_TREE); + gfc_define_builtin ("__builtin_fmal", ftype, BUILT_IN_FMAL, + "fmal", ATTR_CONST_NOTHROW_LEAF_LIST); + ftype = build_function_type_list (double_type_node, double_type_node, + double_type_node, double_type_node, + NULL_TREE); + gfc_define_builtin ("__builtin_fma", ftype, BUILT_IN_FMA, + "fma", ATTR_CONST_NOTHROW_LEAF_LIST); + ftype = build_function_type_list (float_type_node, float_type_node, + float_type_node, float_type_node, + NULL_TREE); + gfc_define_builtin ("__builtin_fmaf", ftype, BUILT_IN_FMAF, + "fmaf", ATTR_CONST_NOTHROW_LEAF_LIST); + gfc_define_builtin ("__emutls_get_address", builtin_types[BT_FN_PTR_PTR], BUILT_IN_EMUTLS_GET_ADDRESS, diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 696aadd..4babd77 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1265,7 +1265,7 @@ enum gfc_omp_reduction_op OMP_REDUCTION_USER }; -enum gfc_omp_depend_op +enum gfc_omp_depend_doacross_op { OMP_DEPEND_UNSET, OMP_DEPEND_IN, @@ -1275,7 +1275,8 @@ enum gfc_omp_depend_op OMP_DEPEND_MUTEXINOUTSET, OMP_DEPEND_DEPOBJ, OMP_DEPEND_SINK_FIRST, - OMP_DEPEND_SINK + OMP_DOACROSS_SINK_FIRST, + OMP_DOACROSS_SINK }; enum gfc_omp_map_op @@ -1343,7 +1344,7 @@ typedef struct gfc_omp_namelist union { gfc_omp_reduction_op reduction_op; - gfc_omp_depend_op depend_op; + gfc_omp_depend_doacross_op depend_doacross_op; gfc_omp_map_op map_op; struct { @@ -1536,17 +1537,17 @@ typedef struct gfc_omp_clauses unsigned nowait:1, ordered:1, untied:1, mergeable:1, ancestor:1; unsigned inbranch:1, notinbranch:1, nogroup:1; unsigned sched_simd:1, sched_monotonic:1, sched_nonmonotonic:1; - unsigned simd:1, threads:1, depend_source:1, destroy:1, order_concurrent:1; + unsigned simd:1, threads:1, doacross_source:1, depend_source:1, destroy:1; unsigned order_unconstrained:1, order_reproducible:1, capture:1; unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1; - unsigned non_rectangular:1; + unsigned non_rectangular:1, order_concurrent:1; ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3; ENUM_BITFIELD (gfc_omp_device_type) device_type:2; ENUM_BITFIELD (gfc_omp_memorder) memorder:3; ENUM_BITFIELD (gfc_omp_memorder) fail:3; ENUM_BITFIELD (gfc_omp_cancel_kind) cancel:3; ENUM_BITFIELD (gfc_omp_proc_bind_kind) proc_bind:3; - ENUM_BITFIELD (gfc_omp_depend_op) depobj_update:4; + ENUM_BITFIELD (gfc_omp_depend_doacross_op) depobj_update:4; ENUM_BITFIELD (gfc_omp_bind_type) bind:2; ENUM_BITFIELD (gfc_omp_at_type) at:2; ENUM_BITFIELD (gfc_omp_severity_type) severity:2; diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index d34e0b5..4b4ecd5 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -246,7 +246,7 @@ including OpenMP and OpenACC support for parallel programming. The GNU Fortran compiler passes the @uref{http://www.fortran-2000.com/ArnaudRecipes/fcvs21_f95.html, NIST Fortran 77 Test Suite}, and produces acceptable results on the -@uref{https://www.netlib.org/lapack/faq.html#1.21, LAPACK Test Suite}. +@uref{https://www.netlib.org/lapack/faq.html, LAPACK Test Suite}. It also provides respectable performance on the @uref{https://polyhedron.com/?page_id=175, Polyhedron Fortran compiler benchmarks} and the @@ -441,7 +441,7 @@ found in the following sections of the documentation. Additionally, the GNU Fortran compilers supports the OpenMP specification (version 4.5 and partial support of the features of the 5.0 version, -@url{https://openmp.org/@/openmp-specifications/}). +@url{https://openmp.org/@/specifications/}). There also is support for the OpenACC specification (targeting version 2.6, @uref{https://www.openacc.org/}). See @uref{https://gcc.gnu.org/wiki/OpenACC} for more information. @@ -455,9 +455,8 @@ version 2.6, @uref{https://www.openacc.org/}). See The Fortran 95 standard specifies in Part 2 (ISO/IEC 1539-2:2000) varying length character strings. While GNU Fortran currently does not support such strings directly, there exist two Fortran implementations -for them, which work with GNU Fortran. They can be found at -@uref{https://www.fortran.com/@/iso_varying_string.f95} and at -@uref{ftp://ftp.nag.co.uk/@/sc22wg5/@/ISO_VARYING_STRING/}. +for them, which work with GNU Fortran. One can be found at +@uref{http://user.astro.wisc.edu/~townsend/static.php?ref=iso-varying-string}. Deferred-length character strings of Fortran 2003 supports part of the features of @code{ISO_VARYING_STRING} and should be considered as @@ -1806,7 +1805,7 @@ It consists of a set of compiler directives, library routines, and environment variables that influence run-time behavior. GNU Fortran strives to be compatible to the -@uref{https://openmp.org/wp/openmp-specifications/, +@uref{https://openmp.org/specifications/, OpenMP Application Program Interface v4.5}. To enable the processing of the OpenMP directive @code{!$omp} in @@ -3788,7 +3787,7 @@ The arguments are passed in the following order @code{CHARACTER} and no C binding is used @item The arguments in the order in which they appear in the Fortran declaration -@item The the present status for optional arguments with value attribute, +@item The present status for optional arguments with value attribute, which are internally passed by value @item The character length and/or coarray token and offset for the first argument which is a @code{CHARACTER} or a nonallocatable coarray dummy diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc index 71eec78..d3e1995 100644 --- a/gcc/fortran/interface.cc +++ b/gcc/fortran/interface.cc @@ -2692,7 +2692,8 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, - if the actual argument is (a substring of) an element of a non-assumed-shape/non-pointer/non-polymorphic array; or - (F2003) if the actual argument is of type character of default/c_char - kind. */ + kind. + - (F2018) if the dummy argument is type(*). */ is_pointer = actual->expr_type == EXPR_VARIABLE ? actual->symtree->n.sym->attr.pointer : false; @@ -2759,6 +2760,14 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, if (ref == NULL && actual->expr_type != EXPR_NULL) { + if (actual->rank == 0 + && formal->ts.type == BT_ASSUMED + && formal->as + && formal->as->type == AS_ASSUMED_SIZE) + /* This is new in F2018, type(*) is new in TS29113, but gfortran does + not differentiate. Thus, if type(*) exists, it is valid; + otherwise, type(*) is already rejected. */ + return true; if (where && (!formal->attr.artificial || (!formal->maybe_array && !maybe_dummy_array_arg (actual)))) diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index c0932f6..58502d3 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -170,7 +170,7 @@ and warnings}. @item Link Options @xref{Link Options,,Options for influencing the linking step}. -@gccoptlist{-static-libgfortran} +@gccoptlist{-static-libgfortran -static-libquadmath} @item Runtime Options @xref{Runtime Options,,Options for influencing runtime behavior}. @@ -1092,6 +1092,11 @@ The type of a function result is declared more than once with the same type. If @item A @code{CHARACTER} variable is declared with negative length. + +@item +With @option{-fopenmp}, for fixed-form source code, when an @code{omx} +vendor-extension sentinel is encountered. (The equivalent @code{ompx}, +used in free-form source code, is diagnosed by default.) @end itemize @item -Wtabs @@ -1425,6 +1430,20 @@ configured, this option has no effect. @end table +@table @gcctabopt +@item -static-libquadmath +@opindex @code{static-libquadmath} +On systems that provide @file{libquadmath} as a shared and a static +library, this option forces the use of the static version. If no +shared version of @file{libquadmath} was built when the compiler was +configured, this option has no effect. + +Please note that the @file{libquadmath} runtime library is licensed under the +GNU Lesser General Public License (LGPL), and linking it statically introduces +requirements when redistributing the resulting binaries. +@end table + + @node Runtime Options @section Influencing runtime behavior @cindex options, runtime diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index cf39712..b18a6d3 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -860,9 +860,13 @@ Fortran Joined Separate ; Documented in common.opt static-libgfortran -Fortran +Driver Statically link the GNU Fortran helper library (libgfortran). +static-libquadmath +Driver +Statically link the GCC Quad-Precision Math Library (libquadmath). + std=f2003 Fortran Conform to the ISO Fortran 2003 standard. diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h index 4328447..79a8c2f 100644 --- a/gcc/fortran/libgfortran.h +++ b/gcc/fortran/libgfortran.h @@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see #define GFC_FPE_TONEAREST 2 #define GFC_FPE_TOWARDZERO 3 #define GFC_FPE_UPWARD 4 +#define GFC_FPE_AWAY 5 /* Size of the buffer required to store FPU state for any target. In particular, this has to be larger than fenv_t on all glibc targets. @@ -187,3 +188,23 @@ typedef enum BT_ASSUMED, BT_UNION, BT_BOZ } bt; + +/* Enumeration of the possible floating-point types. These values + correspond to the hidden arguments of the IEEE_CLASS_TYPE + derived-type of IEEE_ARITHMETIC. */ + +enum { + IEEE_OTHER_VALUE = 0, + IEEE_SIGNALING_NAN, + IEEE_QUIET_NAN, + IEEE_NEGATIVE_INF, + IEEE_NEGATIVE_NORMAL, + IEEE_NEGATIVE_DENORMAL, + IEEE_NEGATIVE_SUBNORMAL = IEEE_NEGATIVE_DENORMAL, + IEEE_NEGATIVE_ZERO, + IEEE_POSITIVE_ZERO, + IEEE_POSITIVE_DENORMAL, + IEEE_POSITIVE_SUBNORMAL = IEEE_POSITIVE_DENORMAL, + IEEE_POSITIVE_NORMAL, + IEEE_POSITIVE_INF +}; diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc index 1aa3053..8b8b6e7 100644 --- a/gcc/fortran/match.cc +++ b/gcc/fortran/match.cc @@ -454,10 +454,11 @@ gfc_match_eos (void) /* Match a literal integer on the input, setting the value on MATCH_YES. Literal ints occur in kind-parameters as well as old-style character length specifications. If cnt is non-NULL it - will be set to the number of digits. */ + will be set to the number of digits. + When gobble_ws is false, do not skip over leading blanks. */ match -gfc_match_small_literal_int (int *value, int *cnt) +gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws) { locus old_loc; char c; @@ -466,7 +467,8 @@ gfc_match_small_literal_int (int *value, int *cnt) old_loc = gfc_current_locus; *value = -1; - gfc_gobble_whitespace (); + if (gobble_ws) + gfc_gobble_whitespace (); c = gfc_next_ascii_char (); if (cnt) *cnt = 0; @@ -608,17 +610,19 @@ gfc_match_label (void) /* See if the current input looks like a name of some sort. Modifies the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long. Note that options.cc restricts max_identifier_length to not more - than GFC_MAX_SYMBOL_LEN. */ + than GFC_MAX_SYMBOL_LEN. + When gobble_ws is false, do not skip over leading blanks. */ match -gfc_match_name (char *buffer) +gfc_match_name (char *buffer, bool gobble_ws) { locus old_loc; int i; char c; old_loc = gfc_current_locus; - gfc_gobble_whitespace (); + if (gobble_ws) + gfc_gobble_whitespace (); c = gfc_next_ascii_char (); if (!(ISALPHA (c) || (c == '_' && flag_allow_leading_underscore))) @@ -1053,15 +1057,17 @@ cleanup: /* Tries to match the next non-whitespace character on the input. - This subroutine does not return MATCH_ERROR. */ + This subroutine does not return MATCH_ERROR. + When gobble_ws is false, do not skip over leading blanks. */ match -gfc_match_char (char c) +gfc_match_char (char c, bool gobble_ws) { locus where; where = gfc_current_locus; - gfc_gobble_whitespace (); + if (gobble_ws) + gfc_gobble_whitespace (); if (gfc_next_ascii_char () == c) return MATCH_YES; diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index 495c93e..1f53e0c 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -45,14 +45,14 @@ extern gfc_access gfc_typebound_default_access; match gfc_match_special_char (gfc_char_t *); match gfc_match_space (void); match gfc_match_eos (void); -match gfc_match_small_literal_int (int *, int *); +match gfc_match_small_literal_int (int *, int *, bool = true); match gfc_match_st_label (gfc_st_label **); match gfc_match_small_int (int *); -match gfc_match_name (char *); +match gfc_match_name (char *, bool = true); match gfc_match_symbol (gfc_symbol **, int); match gfc_match_sym_tree (gfc_symtree **, int); match gfc_match_intrinsic_op (gfc_intrinsic_op *); -match gfc_match_char (char); +match gfc_match_char (char, bool = true); match gfc_match (const char *, ...); match gfc_match_iterator (gfc_iterator *, int); match gfc_match_parens (void); diff --git a/gcc/fortran/mathbuiltins.def b/gcc/fortran/mathbuiltins.def index 615214e..9d55c34 100644 --- a/gcc/fortran/mathbuiltins.def +++ b/gcc/fortran/mathbuiltins.def @@ -60,6 +60,7 @@ OTHER_BUILTIN (CABS, "cabs", cabs, true) OTHER_BUILTIN (COPYSIGN, "copysign", 2, true) OTHER_BUILTIN (CPOW, "cpow", cpow, true) OTHER_BUILTIN (FABS, "fabs", 1, true) +OTHER_BUILTIN (FMA, "fma", 3, true) OTHER_BUILTIN (FMOD, "fmod", 2, true) OTHER_BUILTIN (FREXP, "frexp", frexp, false) OTHER_BUILTIN (LOGB, "logb", 1, true) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index df9cdf4..457e983 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -575,11 +575,13 @@ syntax_error: } -/* Match depend(sink : ...) construct a namelist from it. */ +/* Match doacross(sink : ...) construct a namelist from it; + if depend is true, match legacy 'depend(sink : ...)'. */ static match -gfc_match_omp_depend_sink (gfc_omp_namelist **list) +gfc_match_omp_doacross_sink (gfc_omp_namelist **list, bool depend) { + char n[GFC_MAX_SYMBOL_LEN+1]; gfc_omp_namelist *head, *tail, *p; locus old_loc, cur_loc; gfc_symbol *sym; @@ -591,49 +593,51 @@ gfc_match_omp_depend_sink (gfc_omp_namelist **list) for (;;) { cur_loc = gfc_current_locus; - switch (gfc_match_symbol (&sym, 1)) + + if (gfc_match_name (n) != MATCH_YES) + goto syntax; + if (UNLIKELY (strcmp (n, "omp_all_memory") == 0)) { - case MATCH_YES: - gfc_set_sym_referenced (sym); - p = gfc_get_omp_namelist (); - if (head == NULL) - { - head = tail = p; - head->u.depend_op = OMP_DEPEND_SINK_FIRST; - } - else - { - tail->next = p; - tail = tail->next; - tail->u.depend_op = OMP_DEPEND_SINK; - } - tail->sym = sym; - tail->expr = NULL; - tail->where = cur_loc; - if (UNLIKELY (strcmp (sym->name, "omp_all_memory") == 0)) - { - gfc_error ("%<omp_all_memory%> used with DEPEND kind " - "other than OUT or INOUT at %C"); - goto cleanup; - } - if (gfc_match_char ('+') == MATCH_YES) - { - if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES) - goto syntax; - } - else if (gfc_match_char ('-') == MATCH_YES) - { - if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES) - goto syntax; - tail->expr = gfc_uminus (tail->expr); - } - break; - case MATCH_NO: - goto syntax; - case MATCH_ERROR: + gfc_error ("%<omp_all_memory%> used with dependence-type " + "other than OUT or INOUT at %C"); goto cleanup; } - + sym = NULL; + if (!(strcmp (n, "omp_cur_iteration") == 0)) + { + gfc_symtree *st; + if (gfc_get_ha_sym_tree (n, &st)) + goto syntax; + sym = st->n.sym; + gfc_set_sym_referenced (sym); + } + p = gfc_get_omp_namelist (); + if (head == NULL) + { + head = tail = p; + head->u.depend_doacross_op = (depend ? OMP_DEPEND_SINK_FIRST + : OMP_DOACROSS_SINK_FIRST); + } + else + { + tail->next = p; + tail = tail->next; + tail->u.depend_doacross_op = OMP_DOACROSS_SINK; + } + tail->sym = sym; + tail->expr = NULL; + tail->where = cur_loc; + if (gfc_match_char ('+') == MATCH_YES) + { + if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES) + goto syntax; + } + else if (gfc_match_char ('-') == MATCH_YES) + { + if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES) + goto syntax; + tail->expr = gfc_uminus (tail->expr); + } if (gfc_match_char (')') == MATCH_YES) break; if (gfc_match_char (',') != MATCH_YES) @@ -647,7 +651,7 @@ gfc_match_omp_depend_sink (gfc_omp_namelist **list) return MATCH_YES; syntax: - gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C"); + gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C"); cleanup: gfc_free_omp_namelist (head, false); @@ -987,6 +991,7 @@ enum omp_mask2 OMP_CLAUSE_NOHOST, OMP_CLAUSE_HAS_DEVICE_ADDR, /* OpenMP 5.1 */ OMP_CLAUSE_ENTER, /* OpenMP 5.2 */ + OMP_CLAUSE_DOACROSS, /* OpenMP 5.2 */ /* This must come last. */ OMP_MASK2_LAST }; @@ -1903,18 +1908,26 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, OMP_MAP_RELEASE, true, allow_derived)) continue; - if ((mask & OMP_CLAUSE_DEPEND) - && gfc_match ("depend ( ") == MATCH_YES) + /* DOACROSS: match 'doacross' and 'depend' with sink/source. + DEPEND: match 'depend' but not sink/source. */ + m = MATCH_NO; + if (((mask & OMP_CLAUSE_DOACROSS) + && gfc_match ("doacross ( ") == MATCH_YES) + || (((mask & OMP_CLAUSE_DEPEND) || (mask & OMP_CLAUSE_DOACROSS)) + && (m = gfc_match ("depend ( ")) == MATCH_YES)) { bool has_omp_all_memory; + bool is_depend = m == MATCH_YES; gfc_namespace *ns_iter = NULL, *ns_curr = gfc_current_ns; - match m_it = gfc_match_iterator (&ns_iter, false); + match m_it = MATCH_NO; + if (is_depend) + m_it = gfc_match_iterator (&ns_iter, false); if (m_it == MATCH_ERROR) break; if (m_it == MATCH_YES && gfc_match (" , ") != MATCH_YES) break; m = MATCH_YES; - gfc_omp_depend_op depend_op = OMP_DEPEND_OUT; + gfc_omp_depend_doacross_op depend_op = OMP_DEPEND_OUT; if (gfc_match ("inoutset") == MATCH_YES) depend_op = OMP_DEPEND_INOUTSET; else if (gfc_match ("inout") == MATCH_YES) @@ -1927,34 +1940,77 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, depend_op = OMP_DEPEND_MUTEXINOUTSET; else if (gfc_match ("depobj") == MATCH_YES) depend_op = OMP_DEPEND_DEPOBJ; - else if (!c->depend_source - && gfc_match ("source )") == MATCH_YES) + else if (gfc_match ("source") == MATCH_YES) { if (m_it == MATCH_YES) { gfc_error ("ITERATOR may not be combined with SOURCE " "at %C"); - gfc_free_omp_clauses (c); - return MATCH_ERROR; + goto error; + } + if (!(mask & OMP_CLAUSE_DOACROSS)) + { + gfc_error ("SOURCE at %C not permitted as dependence-type" + " for this directive"); + goto error; + } + if (c->doacross_source) + { + gfc_error ("Duplicated clause with SOURCE dependence-type" + " at %C"); + goto error; + } + gfc_gobble_whitespace (); + m = gfc_match (": "); + if (m != MATCH_YES && !is_depend) + { + gfc_error ("Expected %<:%> at %C"); + goto error; + } + if (gfc_match (")") != MATCH_YES + && !(m == MATCH_YES + && gfc_match ("omp_cur_iteration )") == MATCH_YES)) + { + gfc_error ("Expected %<)%> or %<omp_cur_iteration)%> " + "at %C"); + goto error; } - c->depend_source = true; + c->doacross_source = true; + c->depend_source = is_depend; continue; } - else if (gfc_match ("sink : ") == MATCH_YES) + else if (gfc_match ("sink ") == MATCH_YES) { + if (!(mask & OMP_CLAUSE_DOACROSS)) + { + gfc_error ("SINK at %C not permitted as dependence-type " + "for this directive"); + goto error; + } + if (gfc_match (": ") != MATCH_YES) + { + gfc_error ("Expected %<:%> at %C"); + goto error; + } if (m_it == MATCH_YES) { gfc_error ("ITERATOR may not be combined with SINK " "at %C"); - break; + goto error; } - if (gfc_match_omp_depend_sink (&c->lists[OMP_LIST_DEPEND]) - == MATCH_YES) + m = gfc_match_omp_doacross_sink (&c->lists[OMP_LIST_DEPEND], + is_depend); + if (m == MATCH_YES) continue; - m = MATCH_NO; + goto error; } else m = MATCH_NO; + if (!(mask & OMP_CLAUSE_DEPEND)) + { + gfc_error ("Expected dependence-type SINK or SOURCE at %C"); + goto error; + } head = NULL; if (ns_iter) gfc_current_ns = ns_iter; @@ -1976,7 +2032,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, gfc_omp_namelist *n; for (n = *head; n; n = n->next) { - n->u.depend_op = depend_op; + n->u.depend_doacross_op = depend_op; n->u2.ns = ns_iter; if (ns_iter) ns_iter->refs++; @@ -2480,7 +2536,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, goto error; } } - else + if (step == NULL) { step = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind, @@ -3971,18 +4027,15 @@ gfc_match_omp_depobj (void) if (c->depobj_update == OMP_DEPEND_UNSET && !c->destroy) { - if (!c->depend_source && !c->lists[OMP_LIST_DEPEND]) + if (!c->doacross_source && !c->lists[OMP_LIST_DEPEND]) { gfc_error ("Expected DEPEND, UPDATE, or DESTROY clause at %C"); goto error; } - if (c->depend_source - || c->lists[OMP_LIST_DEPEND]->u.depend_op == OMP_DEPEND_SINK_FIRST - || c->lists[OMP_LIST_DEPEND]->u.depend_op == OMP_DEPEND_SINK - || c->lists[OMP_LIST_DEPEND]->u.depend_op == OMP_DEPEND_DEPOBJ) + if (c->lists[OMP_LIST_DEPEND]->u.depend_doacross_op == OMP_DEPEND_DEPOBJ) { gfc_error ("DEPEND clause at %L of OMP DEPOBJ construct shall not " - "have dependence-type SOURCE, SINK or DEPOBJ", + "have dependence-type DEPOBJ", c->lists[OMP_LIST_DEPEND] ? &c->lists[OMP_LIST_DEPEND]->where : &gfc_current_locus); goto error; @@ -4213,9 +4266,13 @@ gfc_match_omp_declare_simd (void) gfc_omp_declare_simd *ods; bool needs_space = false; - switch (gfc_match (" ( %s ) ", &proc_name)) + switch (gfc_match (" ( ")) { - case MATCH_YES: break; + case MATCH_YES: + if (gfc_match_symbol (&proc_name, /* host assoc = */ true) != MATCH_YES + || gfc_match (" ) ") != MATCH_YES) + return MATCH_ERROR; + break; case MATCH_NO: proc_name = NULL; needs_space = true; break; case MATCH_ERROR: return MATCH_ERROR; } @@ -5984,7 +6041,7 @@ gfc_match_omp_nothing (void) match gfc_match_omp_ordered_depend (void) { - return match_omp (EXEC_OMP_ORDERED, omp_mask (OMP_CLAUSE_DEPEND)); + return match_omp (EXEC_OMP_ORDERED, omp_mask (OMP_CLAUSE_DOACROSS)); } @@ -7053,18 +7110,16 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, if (list == OMP_LIST_DEPEND) { - if (n->u.depend_op == OMP_DEPEND_SINK_FIRST - || n->u.depend_op == OMP_DEPEND_SINK) + if (n->u.depend_doacross_op == OMP_DEPEND_SINK_FIRST + || n->u.depend_doacross_op == OMP_DOACROSS_SINK_FIRST + || n->u.depend_doacross_op == OMP_DOACROSS_SINK) { - if (code->op != EXEC_OMP_ORDERED) - gfc_error ("SINK dependence type only allowed " - "on ORDERED directive at %L", &n->where); - else if (omp_clauses->depend_source) + if (omp_clauses->doacross_source) { - gfc_error ("DEPEND SINK used together with " - "DEPEND SOURCE on the same construct " - "at %L", &n->where); - omp_clauses->depend_source = false; + gfc_error ("Dependence-type SINK used together with" + " SOURCE on the same construct at %L", + &n->where); + omp_clauses->doacross_source = false; } else if (n->expr) { @@ -7074,13 +7129,14 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, gfc_error ("SINK addend not a constant integer " "at %L", &n->where); } + if (n->sym == NULL + && (n->expr == NULL + || mpz_cmp_si (n->expr->value.integer, -1) != 0)) + gfc_error ("omp_cur_iteration at %L requires %<-1%> " + "as logical offset", &n->where); continue; } - else if (code->op == EXEC_OMP_ORDERED) - gfc_error ("Only SOURCE or SINK dependence types " - "are allowed on ORDERED directive at %L", - &n->where); - else if (n->u.depend_op == OMP_DEPEND_DEPOBJ + else if (n->u.depend_doacross_op == OMP_DEPEND_DEPOBJ && !n->expr && (n->sym->ts.type != BT_INTEGER || n->sym->ts.kind @@ -7090,7 +7146,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, "type shall be a scalar integer of " "OMP_DEPEND_KIND kind", n->sym->name, &n->where); - else if (n->u.depend_op == OMP_DEPEND_DEPOBJ + else if (n->u.depend_doacross_op == OMP_DEPEND_DEPOBJ && n->expr && (!gfc_resolve_expr (n->expr) || n->expr->ts.type != BT_INTEGER @@ -7386,7 +7442,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, || code->op == EXEC_OACC_PARALLEL || code->op == EXEC_OACC_SERIAL)) check_array_not_assumed (n->sym, n->where, name); - else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE) + else if (list != OMP_LIST_UNIFORM + && n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE) gfc_error ("Assumed size array %qs in %s clause at %L", n->sym->name, name, &n->where); if (n->sym->attr.in_namelist && !is_reduction) @@ -7568,10 +7625,6 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, linear_op = n->u.linear.op; } } - else if (omp_clauses->orderedc) - gfc_error ("LINEAR clause specified together with " - "ORDERED clause with argument at %L", - &n->where); else if (n->u.linear.op != OMP_LINEAR_REF && n->sym->ts.type != BT_INTEGER) gfc_error ("LINEAR variable %qs must be INTEGER " @@ -7755,9 +7808,6 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, resolve_scalar_int_expr (el->expr, "WAIT"); if (omp_clauses->collapse && omp_clauses->tile_list) gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code->loc); - if (omp_clauses->depend_source && code->op != EXEC_OMP_ORDERED) - gfc_error ("SOURCE dependence type only allowed " - "on ORDERED directive at %L", &code->loc); if (omp_clauses->message) { gfc_expr *expr = omp_clauses->message; @@ -9560,6 +9610,7 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_CANCEL: case EXEC_OMP_ERROR: case EXEC_OMP_MASKED: + case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_MASKED: diff --git a/gcc/fortran/options.cc b/gcc/fortran/options.cc index d0fa634..08afb78 100644 --- a/gcc/fortran/options.cc +++ b/gcc/fortran/options.cc @@ -685,13 +685,6 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, gfc_option.source_form = FORM_FREE; break; - case OPT_static_libgfortran: -#ifndef HAVE_LD_STATIC_DYNAMIC - gfc_fatal_error ("%<-static-libgfortran%> is not supported in this " - "configuration"); -#endif - break; - case OPT_fintrinsic_modules_path: case OPT_fintrinsic_modules_path_: diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index 0b4c596..5b13441 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -1026,7 +1026,8 @@ decode_omp_directive (void) matcho ("loop", gfc_match_omp_loop, ST_OMP_LOOP); break; case 'o': - if (gfc_match ("ordered depend (") == MATCH_YES) + if (gfc_match ("ordered depend (") == MATCH_YES + || gfc_match ("ordered doacross (") == MATCH_YES) { gfc_current_locus = old_locus; if (!flag_openmp) @@ -5709,7 +5710,7 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) } return st; } - else if (st != omp_end_st) + else if (st != omp_end_st || block_construct) { unexpected_statement (st); st = next_statement (); diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc index 3f01f67..19f2e78 100644 --- a/gcc/fortran/primary.cc +++ b/gcc/fortran/primary.cc @@ -45,11 +45,11 @@ match_kind_param (int *kind, int *is_iso_c) *is_iso_c = 0; - m = gfc_match_small_literal_int (kind, NULL); + m = gfc_match_small_literal_int (kind, NULL, false); if (m != MATCH_NO) return m; - m = gfc_match_name (name); + m = gfc_match_name (name, false); if (m != MATCH_YES) return m; @@ -95,7 +95,7 @@ get_kind (int *is_iso_c) *is_iso_c = 0; - if (gfc_match_char ('_') != MATCH_YES) + if (gfc_match_char ('_', false) != MATCH_YES) return -2; m = match_kind_param (&kind, is_iso_c); @@ -1074,17 +1074,9 @@ match_string_constant (gfc_expr **result) c = gfc_next_char (); } - if (c == ' ') - { - gfc_gobble_whitespace (); - c = gfc_next_char (); - } - if (c != '_') goto no_match; - gfc_gobble_whitespace (); - c = gfc_next_char (); if (c != '\'' && c != '"') goto no_match; diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index ca11475..ae7ebb6 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -11803,6 +11803,7 @@ deferred_op_assign (gfc_code **code, gfc_namespace *ns) if (!((*code)->expr1->ts.type == BT_CHARACTER && (*code)->expr1->ts.deferred && (*code)->expr1->rank + && (*code)->expr2->ts.type == BT_CHARACTER && (*code)->expr2->expr_type == EXPR_OP)) return false; diff --git a/gcc/fortran/scanner.cc b/gcc/fortran/scanner.cc index 2dff251..fa1d9cb 100644 --- a/gcc/fortran/scanner.cc +++ b/gcc/fortran/scanner.cc @@ -982,8 +982,9 @@ static bool skip_fixed_omp_sentinel (locus *start) { gfc_char_t c; - if (((c = next_char ()) == 'm' || c == 'M') - && ((c = next_char ()) == 'p' || c == 'P')) + if ((c = next_char ()) != 'm' && c != 'M') + return false; + if ((c = next_char ()) == 'p' || c == 'P') { c = next_char (); if (c != '\n' @@ -1005,6 +1006,9 @@ skip_fixed_omp_sentinel (locus *start) } } } + else if (UNLIKELY (c == 'x' || c == 'X')) + gfc_warning_now (OPT_Wsurprising, + "Ignoring '!$omx' vendor-extension sentinel at %C"); return false; } diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc index fb72599..c0fbd0e 100644 --- a/gcc/fortran/simplify.cc +++ b/gcc/fortran/simplify.cc @@ -3380,6 +3380,13 @@ gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y) k = gfc_validate_kind (x->ts.type, x->ts.kind, false); result = gfc_copy_expr (x); + /* Drop any separate memory representation of x to avoid potential + inconsistencies in result. */ + if (result->representation.string) + { + free (result->representation.string); + result->representation.string = NULL; + } convert_mpz_to_unsigned (result->value.integer, gfc_integer_kinds[k].bit_size); @@ -3471,6 +3478,13 @@ gfc_simplify_ibset (gfc_expr *x, gfc_expr *y) k = gfc_validate_kind (x->ts.type, x->ts.kind, false); result = gfc_copy_expr (x); + /* Drop any separate memory representation of x to avoid potential + inconsistencies in result. */ + if (result->representation.string) + { + free (result->representation.string); + result->representation.string = NULL; + } convert_mpz_to_unsigned (result->value.integer, gfc_integer_kinds[k].bit_size); @@ -5881,6 +5895,7 @@ gfc_simplify_findloc (gfc_expr *array, gfc_expr *value, gfc_expr *dim, bool back_val = false; if (!is_constant_array_expr (array) + || array->shape == NULL || !gfc_is_constant_expr (dim)) return NULL; @@ -6417,7 +6432,7 @@ gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector) /* Copy only those elements of ARRAY to RESULT whose MASK equals .TRUE.. */ mask_ctor = gfc_constructor_first (mask->value.constructor); - while (mask_ctor) + while (mask_ctor && array_ctor) { if (mask_ctor->expr->value.logical) { @@ -7522,8 +7537,9 @@ simplify_size (gfc_expr *array, gfc_expr *dim, int k) } for (ref = array->ref; ref; ref = ref->next) - if (ref->type == REF_ARRAY && ref->u.ar.as) - gfc_resolve_array_spec (ref->u.ar.as, 0); + if (ref->type == REF_ARRAY && ref->u.ar.as + && !gfc_resolve_array_spec (ref->u.ar.as, 0)) + return NULL; if (dim == NULL) { diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 850007f..7895d03 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -7220,16 +7220,15 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, else goto end_pointer_check; + tmp = parmse.expr; if (fsym && fsym->ts.type == BT_CLASS) { - tmp = build_fold_indirect_ref_loc (input_location, - parmse.expr); + if (POINTER_TYPE_P (TREE_TYPE (tmp))) + tmp = build_fold_indirect_ref_loc (input_location, tmp); tmp = gfc_class_data_get (tmp); if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp))) tmp = gfc_conv_descriptor_data_get (tmp); } - else - tmp = parmse.expr; /* If the argument is passed by value, we need to strip the INDIRECT_REF. */ @@ -11436,6 +11435,9 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs, class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr)) ? gfc_class_data_get (lse->expr) : lse->expr; + if (!POINTER_TYPE_P (TREE_TYPE (class_han))) + class_han = gfc_build_addr_expr (NULL_TREE, class_han); + /* Allocate block. */ gfc_init_block (&alloc); gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE); diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 9d91278..bb93802 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-array.h" #include "dependency.h" /* For CAF array alias analysis. */ #include "attribs.h" +#include "realmpfr.h" /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */ @@ -694,7 +695,7 @@ gfc_build_intrinsic_lib_fndecls (void) C99-like library functions. For now, we only handle _Float128 q-suffixed or IEC 60559 f128-suffixed functions. */ - tree type, complex_type, func_1, func_2, func_cabs, func_frexp; + tree type, complex_type, func_1, func_2, func_3, func_cabs, func_frexp; tree func_iround, func_lround, func_llround, func_scalbn, func_cpow; memset (quad_decls, 0, sizeof(tree) * (END_BUILTINS + 1)); @@ -714,6 +715,8 @@ gfc_build_intrinsic_lib_fndecls (void) type, NULL_TREE); /* type (*) (type, type) */ func_2 = build_function_type_list (type, type, type, NULL_TREE); + /* type (*) (type, type, type) */ + func_3 = build_function_type_list (type, type, type, type, NULL_TREE); /* type (*) (type, &int) */ func_frexp = build_function_type_list (type, @@ -9780,7 +9783,7 @@ conv_ieee_function_args (gfc_se *se, gfc_expr *expr, tree *argarray, } -/* Generate code for intrinsics IEEE_IS_NAN, IEEE_IS_FINITE, +/* Generate code for intrinsics IEEE_IS_NAN, IEEE_IS_FINITE and IEEE_UNORDERED, which translate directly to GCC type-generic built-ins. */ @@ -9800,6 +9803,23 @@ conv_intrinsic_ieee_builtin (gfc_se * se, gfc_expr * expr, } +/* Generate code for intrinsics IEEE_SIGNBIT. */ + +static void +conv_intrinsic_ieee_signbit (gfc_se * se, gfc_expr * expr) +{ + tree arg, signbit; + + conv_ieee_function_args (se, expr, &arg, 1); + signbit = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_SIGNBIT), + 1, arg); + signbit = fold_build2_loc (input_location, NE_EXPR, logical_type_node, + signbit, integer_zero_node); + se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), signbit); +} + + /* Generate code for IEEE_IS_NORMAL intrinsic: IEEE_IS_NORMAL(x) --> (__builtin_isnormal(x) || x == 0) */ @@ -10013,6 +10033,223 @@ conv_intrinsic_ieee_copy_sign (gfc_se * se, gfc_expr * expr) } +/* Generate code for IEEE_CLASS. */ + +static void +conv_intrinsic_ieee_class (gfc_se *se, gfc_expr *expr) +{ + tree arg, c, t1, t2, t3, t4; + + /* Convert arg, evaluate it only once. */ + conv_ieee_function_args (se, expr, &arg, 1); + arg = gfc_evaluate_now (arg, &se->pre); + + c = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_FPCLASSIFY), 6, + build_int_cst (integer_type_node, IEEE_QUIET_NAN), + build_int_cst (integer_type_node, + IEEE_POSITIVE_INF), + build_int_cst (integer_type_node, + IEEE_POSITIVE_NORMAL), + build_int_cst (integer_type_node, + IEEE_POSITIVE_DENORMAL), + build_int_cst (integer_type_node, + IEEE_POSITIVE_ZERO), + arg); + c = gfc_evaluate_now (c, &se->pre); + t1 = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, + c, build_int_cst (integer_type_node, + IEEE_QUIET_NAN)); + t2 = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_ISSIGNALING), 1, + arg); + t2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, + t2, build_zero_cst (TREE_TYPE (t2))); + t1 = fold_build2_loc (input_location, TRUTH_AND_EXPR, + logical_type_node, t1, t2); + t3 = fold_build2_loc (input_location, GE_EXPR, logical_type_node, + c, build_int_cst (integer_type_node, + IEEE_POSITIVE_ZERO)); + t4 = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_SIGNBIT), 1, + arg); + t4 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, + t4, build_zero_cst (TREE_TYPE (t4))); + t3 = fold_build2_loc (input_location, TRUTH_AND_EXPR, + logical_type_node, t3, t4); + int s = IEEE_NEGATIVE_ZERO + IEEE_POSITIVE_ZERO; + gcc_assert (IEEE_NEGATIVE_INF == s - IEEE_POSITIVE_INF); + gcc_assert (IEEE_NEGATIVE_NORMAL == s - IEEE_POSITIVE_NORMAL); + gcc_assert (IEEE_NEGATIVE_DENORMAL == s - IEEE_POSITIVE_DENORMAL); + gcc_assert (IEEE_NEGATIVE_SUBNORMAL == s - IEEE_POSITIVE_SUBNORMAL); + gcc_assert (IEEE_NEGATIVE_ZERO == s - IEEE_POSITIVE_ZERO); + t4 = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (c), + build_int_cst (TREE_TYPE (c), s), c); + t3 = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (c), + t3, t4, c); + t1 = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (c), t1, + build_int_cst (TREE_TYPE (c), IEEE_SIGNALING_NAN), + t3); + tree type = gfc_typenode_for_spec (&expr->ts); + /* Perform a quick sanity check that the return type is + IEEE_CLASS_TYPE derived type defined in + libgfortran/ieee/ieee_arithmetic.F90 + Primarily check that it is a derived type with a single + member in it. */ + gcc_assert (TREE_CODE (type) == RECORD_TYPE); + tree field = NULL_TREE; + for (tree f = TYPE_FIELDS (type); f != NULL_TREE; f = DECL_CHAIN (f)) + if (TREE_CODE (f) == FIELD_DECL) + { + gcc_assert (field == NULL_TREE); + field = f; + } + gcc_assert (field); + t1 = fold_convert (TREE_TYPE (field), t1); + se->expr = build_constructor_single (type, field, t1); +} + + +/* Generate code for IEEE_VALUE. */ + +static void +conv_intrinsic_ieee_value (gfc_se *se, gfc_expr *expr) +{ + tree args[2], arg, ret, tmp; + stmtblock_t body; + + /* Convert args, evaluate the second one only once. */ + conv_ieee_function_args (se, expr, args, 2); + arg = gfc_evaluate_now (args[1], &se->pre); + + tree type = TREE_TYPE (arg); + /* Perform a quick sanity check that the second argument's type is + IEEE_CLASS_TYPE derived type defined in + libgfortran/ieee/ieee_arithmetic.F90 + Primarily check that it is a derived type with a single + member in it. */ + gcc_assert (TREE_CODE (type) == RECORD_TYPE); + tree field = NULL_TREE; + for (tree f = TYPE_FIELDS (type); f != NULL_TREE; f = DECL_CHAIN (f)) + if (TREE_CODE (f) == FIELD_DECL) + { + gcc_assert (field == NULL_TREE); + field = f; + } + gcc_assert (field); + arg = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), + arg, field, NULL_TREE); + arg = gfc_evaluate_now (arg, &se->pre); + + type = gfc_typenode_for_spec (&expr->ts); + gcc_assert (TREE_CODE (type) == REAL_TYPE); + ret = gfc_create_var (type, NULL); + + gfc_init_block (&body); + + tree end_label = gfc_build_label_decl (NULL_TREE); + for (int c = IEEE_SIGNALING_NAN; c <= IEEE_POSITIVE_INF; ++c) + { + tree label = gfc_build_label_decl (NULL_TREE); + tree low = build_int_cst (TREE_TYPE (arg), c); + tmp = build_case_label (low, low, label); + gfc_add_expr_to_block (&body, tmp); + + REAL_VALUE_TYPE real; + int k; + switch (c) + { + case IEEE_SIGNALING_NAN: + real_nan (&real, "", 0, TYPE_MODE (type)); + break; + case IEEE_QUIET_NAN: + real_nan (&real, "", 1, TYPE_MODE (type)); + break; + case IEEE_NEGATIVE_INF: + real_inf (&real); + real = real_value_negate (&real); + break; + case IEEE_NEGATIVE_NORMAL: + real_from_integer (&real, TYPE_MODE (type), -42, SIGNED); + break; + case IEEE_NEGATIVE_DENORMAL: + k = gfc_validate_kind (BT_REAL, expr->ts.kind, false); + real_from_mpfr (&real, gfc_real_kinds[k].tiny, + type, GFC_RND_MODE); + real_arithmetic (&real, RDIV_EXPR, &real, &dconst2); + real = real_value_negate (&real); + break; + case IEEE_NEGATIVE_ZERO: + real_from_integer (&real, TYPE_MODE (type), 0, SIGNED); + real = real_value_negate (&real); + break; + case IEEE_POSITIVE_ZERO: + /* Make this also the default: label. The other possibility + would be to add a separate default: label followed by + __builtin_unreachable (). */ + label = gfc_build_label_decl (NULL_TREE); + tmp = build_case_label (NULL_TREE, NULL_TREE, label); + gfc_add_expr_to_block (&body, tmp); + real_from_integer (&real, TYPE_MODE (type), 0, SIGNED); + break; + case IEEE_POSITIVE_DENORMAL: + k = gfc_validate_kind (BT_REAL, expr->ts.kind, false); + real_from_mpfr (&real, gfc_real_kinds[k].tiny, + type, GFC_RND_MODE); + real_arithmetic (&real, RDIV_EXPR, &real, &dconst2); + break; + case IEEE_POSITIVE_NORMAL: + real_from_integer (&real, TYPE_MODE (type), 42, SIGNED); + break; + case IEEE_POSITIVE_INF: + real_inf (&real); + break; + default: + gcc_unreachable (); + } + + tree val = build_real (type, real); + gfc_add_modify (&body, ret, val); + + tmp = build1_v (GOTO_EXPR, end_label); + gfc_add_expr_to_block (&body, tmp); + } + + tmp = gfc_finish_block (&body); + tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, arg, tmp); + gfc_add_expr_to_block (&se->pre, tmp); + + tmp = build1_v (LABEL_EXPR, end_label); + gfc_add_expr_to_block (&se->pre, tmp); + + se->expr = ret; +} + + +/* Generate code for IEEE_FMA. */ + +static void +conv_intrinsic_ieee_fma (gfc_se * se, gfc_expr * expr) +{ + tree args[3], decl, call; + int argprec; + + conv_ieee_function_args (se, expr, args, 3); + + /* All three arguments should have the same type. */ + gcc_assert (TYPE_PRECISION (TREE_TYPE (args[0])) == TYPE_PRECISION (TREE_TYPE (args[1]))); + gcc_assert (TYPE_PRECISION (TREE_TYPE (args[0])) == TYPE_PRECISION (TREE_TYPE (args[2]))); + + /* Call the type-generic FMA built-in. */ + argprec = TYPE_PRECISION (TREE_TYPE (args[0])); + decl = builtin_decl_for_precision (BUILT_IN_FMA, argprec); + call = build_call_expr_loc_array (input_location, decl, 3, args); + + /* Convert to the final type. */ + se->expr = fold_convert (TREE_TYPE (args[0]), call); +} + + /* Generate code for an intrinsic function from the IEEE_ARITHMETIC module. */ @@ -10027,6 +10264,8 @@ gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr) conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISFINITE, 1); else if (startswith (name, "_gfortran_ieee_unordered")) conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISUNORDERED, 2); + else if (startswith (name, "_gfortran_ieee_signbit")) + conv_intrinsic_ieee_signbit (se, expr); else if (startswith (name, "_gfortran_ieee_is_normal")) conv_intrinsic_ieee_is_normal (se, expr); else if (startswith (name, "_gfortran_ieee_is_negative")) @@ -10043,6 +10282,12 @@ gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr) conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_LOGB); else if (startswith (name, "_gfortran_ieee_rint")) conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_RINT); + else if (startswith (name, "ieee_class_") && ISDIGIT (name[11])) + conv_intrinsic_ieee_class (se, expr); + else if (startswith (name, "ieee_value_") && ISDIGIT (name[11])) + conv_intrinsic_ieee_value (se, expr); + else if (startswith (name, "_gfortran_ieee_fma")) + conv_intrinsic_ieee_fma (se, expr); else /* It is not among the functions we translate directly. We return false, so a library function call is emitted. */ diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index de27ed5..8e9d534 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -2864,15 +2864,18 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, gfc_init_block (&iter_block); prev = n; if (list == OMP_LIST_DEPEND - && n->u.depend_op == OMP_DEPEND_SINK_FIRST) + && (n->u.depend_doacross_op == OMP_DOACROSS_SINK_FIRST + || n->u.depend_doacross_op == OMP_DEPEND_SINK_FIRST)) { tree vec = NULL_TREE; unsigned int i; + bool is_depend + = n->u.depend_doacross_op == OMP_DEPEND_SINK_FIRST; for (i = 0; ; i++) { tree addend = integer_zero_node, t; bool neg = false; - if (n->expr) + if (n->sym && n->expr) { addend = gfc_conv_constant_to_tree (n->expr); if (TREE_CODE (addend) == INTEGER_CST @@ -2883,7 +2886,11 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, TREE_TYPE (addend), addend); } } - t = gfc_trans_omp_variable (n->sym, false); + + if (n->sym == NULL) + t = null_pointer_node; /* "omp_cur_iteration - 1". */ + else + t = gfc_trans_omp_variable (n->sym, false); if (t != error_mark_node) { if (i < vec_safe_length (doacross_steps) @@ -2897,10 +2904,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, } vec = tree_cons (addend, t, vec); if (neg) - OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1; + OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1; } if (n->next == NULL - || n->next->u.depend_op != OMP_DEPEND_SINK) + || n->next->u.depend_doacross_op != OMP_DOACROSS_SINK) break; n = n->next; } @@ -2908,8 +2915,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, continue; tree node = build_omp_clause (input_location, - OMP_CLAUSE_DEPEND); - OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_SINK; + OMP_CLAUSE_DOACROSS); + OMP_CLAUSE_DOACROSS_KIND (node) = OMP_CLAUSE_DOACROSS_SINK; + OMP_CLAUSE_DOACROSS_DEPEND (node) = is_depend; OMP_CLAUSE_DECL (node) = nreverse (vec); omp_clauses = gfc_trans_add_clause (node, omp_clauses); continue; @@ -2961,7 +2969,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr); } if (list == OMP_LIST_DEPEND) - switch (n->u.depend_op) + switch (n->u.depend_doacross_op) { case OMP_DEPEND_IN: OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN; @@ -3117,30 +3125,16 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, tree present = gfc_omp_check_optional_argument (decl, true); if (openacc && n->sym->ts.type == BT_CLASS) { - tree type = TREE_TYPE (decl); if (n->sym->attr.optional) sorry ("optional class parameter"); - if (POINTER_TYPE_P (type)) - { - node4 = build_omp_clause (input_location, - OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER); - OMP_CLAUSE_DECL (node4) = decl; - OMP_CLAUSE_SIZE (node4) = size_int (0); - decl = build_fold_indirect_ref (decl); - } tree ptr = gfc_class_data_get (decl); ptr = build_fold_indirect_ref (ptr); OMP_CLAUSE_DECL (node) = ptr; OMP_CLAUSE_SIZE (node) = gfc_class_vtab_size_get (decl); node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET); - OMP_CLAUSE_DECL (node2) = decl; - OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type); - node3 = build_omp_clause (input_location, OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_ATTACH_DETACH); - OMP_CLAUSE_DECL (node3) = gfc_class_data_get (decl); - OMP_CLAUSE_SIZE (node3) = size_int (0); + OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_ATTACH_DETACH); + OMP_CLAUSE_DECL (node2) = gfc_class_data_get (decl); + OMP_CLAUSE_SIZE (node2) = size_int (0); goto finalize_map_clause; } else if (POINTER_TYPE_P (TREE_TYPE (decl)) @@ -4252,10 +4246,11 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, omp_clauses = gfc_trans_add_clause (c, omp_clauses); } - if (clauses->depend_source) + if (clauses->doacross_source) { - c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DEPEND); - OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_SOURCE; + c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DOACROSS); + OMP_CLAUSE_DOACROSS_KIND (c) = OMP_CLAUSE_DOACROSS_SOURCE; + OMP_CLAUSE_DOACROSS_DEPEND (c) = clauses->depend_source; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } @@ -5117,7 +5112,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, init = make_tree_vec (collapse); cond = make_tree_vec (collapse); incr = make_tree_vec (collapse); - orig_decls = clauses->orderedc ? make_tree_vec (collapse) : NULL_TREE; + orig_decls = clauses->ordered ? make_tree_vec (collapse) : NULL_TREE; if (pblock == NULL) { @@ -5217,6 +5212,10 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, MODIFY_EXPR, type, dovar, TREE_VEC_ELT (incr, i)); + if (orig_decls && !clauses->orderedc) + orig_decls = NULL; + else if (orig_decls) + TREE_VEC_ELT (orig_decls, i) = dovar_decl; } else { @@ -5257,9 +5256,9 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, vec_safe_grow_cleared (doacross_steps, clauses->orderedc, true); (*doacross_steps)[i] = step; } + if (orig_decls) + TREE_VEC_ELT (orig_decls, i) = dovar_decl; } - if (orig_decls) - TREE_VEC_ELT (orig_decls, i) = dovar_decl; if (dovar_found == 3 && op == EXEC_OMP_SIMD @@ -5626,7 +5625,7 @@ gfc_trans_omp_depobj (gfc_code *code) int k = -1; /* omp_clauses->destroy */ if (!code->ext.omp_clauses->destroy) switch (code->ext.omp_clauses->depobj_update != OMP_DEPEND_UNSET - ? code->ext.omp_clauses->depobj_update : n->u.depend_op) + ? code->ext.omp_clauses->depobj_update : n->u.depend_doacross_op) { case OMP_DEPEND_IN: k = GOMP_DEPEND_IN; break; case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break; diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index 0ea7c74..c062a5b 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -3054,12 +3054,23 @@ create_fn_spec (gfc_symbol *sym, tree fntype) for (f = gfc_sym_get_dummy_args (sym); f; f = f->next) if (spec_len < sizeof (spec)) { - if (!f->sym || f->sym->attr.pointer || f->sym->attr.target + bool is_class = false; + bool is_pointer = false; + + if (f->sym) + { + is_class = f->sym->ts.type == BT_CLASS && CLASS_DATA (f->sym) + && f->sym->attr.class_ok; + is_pointer = is_class ? CLASS_DATA (f->sym)->attr.class_pointer + : f->sym->attr.pointer; + } + + if (f->sym == NULL || is_pointer || f->sym->attr.target || f->sym->attr.external || f->sym->attr.cray_pointer || (f->sym->ts.type == BT_DERIVED && (f->sym->ts.u.derived->attr.proc_pointer_comp || f->sym->ts.u.derived->attr.pointer_comp)) - || (f->sym->ts.type == BT_CLASS + || (is_class && (CLASS_DATA (f->sym)->ts.u.derived->attr.proc_pointer_comp || CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp)) || (f->sym->ts.type == BT_INTEGER && f->sym->ts.is_c_interop)) |