aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-09-22 06:29:20 -0700
committerIan Lance Taylor <iant@golang.org>2022-09-22 06:29:20 -0700
commit795cffe109e28b248a54b8ee583cbae48368c2a7 (patch)
tree0c12b075c51c0d5097f26953835ae540d9f2f501 /gcc/fortran
parent9f62ed218fa656607740b386c0caa03e65dcd283 (diff)
parentf35be1268c996d993ab0b4ff329734d467474445 (diff)
downloadgcc-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/ChangeLog252
-rw-r--r--gcc/fortran/decl.cc3
-rw-r--r--gcc/fortran/dump-parse-tree.cc38
-rw-r--r--gcc/fortran/expr.cc3
-rw-r--r--gcc/fortran/f95-lang.cc23
-rw-r--r--gcc/fortran/gfortran.h13
-rw-r--r--gcc/fortran/gfortran.texi13
-rw-r--r--gcc/fortran/interface.cc11
-rw-r--r--gcc/fortran/invoke.texi21
-rw-r--r--gcc/fortran/lang.opt6
-rw-r--r--gcc/fortran/libgfortran.h21
-rw-r--r--gcc/fortran/match.cc24
-rw-r--r--gcc/fortran/match.h6
-rw-r--r--gcc/fortran/mathbuiltins.def1
-rw-r--r--gcc/fortran/openmp.cc235
-rw-r--r--gcc/fortran/options.cc7
-rw-r--r--gcc/fortran/parse.cc5
-rw-r--r--gcc/fortran/primary.cc14
-rw-r--r--gcc/fortran/resolve.cc1
-rw-r--r--gcc/fortran/scanner.cc8
-rw-r--r--gcc/fortran/simplify.cc22
-rw-r--r--gcc/fortran/trans-expr.cc10
-rw-r--r--gcc/fortran/trans-intrinsic.cc249
-rw-r--r--gcc/fortran/trans-openmp.cc63
-rw-r--r--gcc/fortran/trans-types.cc15
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))