Re: GCC 13.0.0 Status Report (2022-11-14), Stage 3 in effect now
On 11/14/22 18:21, Xi Ruoyao wrote: > Hi Martin, > Hello. > Is it allowed to merge libsanitizer from LLVM in stage 3? If not I'd > like to cherry pick some commits from LLVM [to fix some stupid errors > I've made in LoongArch libasan :(]. I'm sorry but I was really busy with the porting of the documentation to Sphinx. Anyway, yes, we should make one one libsanitizer merge, but RM should likely approve it: Richi, Jakub, do you support it? Thanks, Martin > > On Mon, 2022-11-14 at 13:21 +, Richard Biener via Gcc-patches wrote: >> Status >> == >> >> The GCC development branch which will become GCC 13 is now in >> bugfixing mode (Stage 3) until the end of Jan 15th. >> >> As usual the first weeks of Stage 3 are used to feature patches >> posted late during Stage 1. At some point unreviewed features >> need to be postponed for the next Stage 1. >> >> >> Quality Data >> >> >> Priority # Change from last report >> --- --- >> P1 33 >> P2 473 >> P3 113 + 29 >> P4 253 + 6 >> P5 25 >> --- --- >> Total P1-P3 619 + 29 >> Total 897 + 35 >> >> >> Previous Report >> === >> >> https://gcc.gnu.org/pipermail/gcc/2022-October/239690.html >
Re: GCC 13.0.0 Status Report (2022-11-14), Stage 3 in effect now
On Tue, Nov 15, 2022 at 11:02:53AM +0100, Martin Liška wrote: > > Is it allowed to merge libsanitizer from LLVM in stage 3? If not I'd > > like to cherry pick some commits from LLVM [to fix some stupid errors > > I've made in LoongArch libasan :(]. > > I'm sorry but I was really busy with the porting of the documentation to > Sphinx. > > Anyway, yes, we should make one one libsanitizer merge, but RM should likely > approve it: Richi, Jakub, do you support it? Could you please prepare a patch, so that we can see how much actually changed and decide based on that whether to go for a merge or cherry-picking one or more commits? I think last merge was done by you at the end of August, so we have 2.5 months of changes to potentially merge. Jakub
Re: GCC 13.0.0 Status Report (2022-11-14), Stage 3 in effect now
On 11/15/22 11:07, Jakub Jelinek wrote: > On Tue, Nov 15, 2022 at 11:02:53AM +0100, Martin Liška wrote: >>> Is it allowed to merge libsanitizer from LLVM in stage 3? If not I'd >>> like to cherry pick some commits from LLVM [to fix some stupid errors >>> I've made in LoongArch libasan :(]. >> >> I'm sorry but I was really busy with the porting of the documentation to >> Sphinx. >> >> Anyway, yes, we should make one one libsanitizer merge, but RM should likely >> approve it: Richi, Jakub, do you support it? > > Could you please prepare a patch, so that we can see how much actually > changed and decide based on that whether to go for a merge or cherry-picking > one or more commits? Sure, there it is. There's a minor change in output format that I address in 0003 patch. Apart from that, I was able to run all tests on x86_64-linux-gnu. Patch statistics: 46 files changed, 524 insertions(+), 252 deletions(-) I'm running build on ppc64le and if you're fine, I'm going to finish a proper libsanitizer testing procedure. Martin > I think last merge was done by you at the end of August, so we have > 2.5 months of changes to potentially merge. > > Jakub > From b9da933ec8860e0c217e2f6fc08f08687d40725f Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 15 Nov 2022 12:02:36 +0100 Subject: [PATCH 3/3] asan: update expected format based on ASAN gcc/testsuite/ChangeLog: * c-c++-common/asan/global-overflow-1.c: Update expected format. * c-c++-common/asan/heap-overflow-1.c: Likewise. * c-c++-common/asan/strlen-overflow-1.c: Likewise. * c-c++-common/asan/strncpy-overflow-1.c: Likewise. * c-c++-common/hwasan/heap-overflow.c: Likewise. * g++.dg/asan/asan_mem_test.cc: Likewise. * g++.dg/asan/asan_oob_test.cc: Likewise. * g++.dg/asan/asan_str_test.cc: Likewise. * g++.dg/asan/asan_test.cc: Likewise. * g++.dg/asan/large-func-test-1.C: Likewise. --- .../c-c++-common/asan/global-overflow-1.c | 2 +- .../c-c++-common/asan/heap-overflow-1.c | 2 +- .../c-c++-common/asan/strlen-overflow-1.c | 2 +- .../c-c++-common/asan/strncpy-overflow-1.c| 2 +- .../c-c++-common/hwasan/heap-overflow.c | 2 +- gcc/testsuite/g++.dg/asan/asan_mem_test.cc| 20 +-- gcc/testsuite/g++.dg/asan/asan_oob_test.cc| 12 +++ gcc/testsuite/g++.dg/asan/asan_str_test.cc| 4 +-- gcc/testsuite/g++.dg/asan/asan_test.cc| 36 +-- gcc/testsuite/g++.dg/asan/large-func-test-1.C | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c index ec412231be0..b97801da2b7 100644 --- a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c @@ -25,5 +25,5 @@ int main() { /* { dg-skip-if "inaccurate debug info" { mips*-*-* } { "*" } { "-O0" } } */ /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output "#0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*global-overflow-1.c:20|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r).*" } */ -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */ +/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes after global variable" } */ /* { dg-output ".*YYY\[^\n\r]* of size 10\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c index 7ef048e636f..7d8744852ae 100644 --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c @@ -25,7 +25,7 @@ int main(int argc, char **argv) { /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output "#0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output "#0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output "#1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c index 86a79fd5d06..34c20c8ed50 100644 --- a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c @@ -21,4 +21,4 @@ int main () { /* { dg-output "READ of size 2 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output "#1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strlen-overflow-1.c:19|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } *
Re: GCC 13.0.0 Status Report (2022-11-14), Stage 3 in effect now
On Tue, Nov 15, 2022 at 01:49:36PM +0100, Martin Liška wrote: > On 11/15/22 11:07, Jakub Jelinek wrote: > > On Tue, Nov 15, 2022 at 11:02:53AM +0100, Martin Liška wrote: > >>> Is it allowed to merge libsanitizer from LLVM in stage 3? If not I'd > >>> like to cherry pick some commits from LLVM [to fix some stupid errors > >>> I've made in LoongArch libasan :(]. > >> > >> I'm sorry but I was really busy with the porting of the documentation to > >> Sphinx. > >> > >> Anyway, yes, we should make one one libsanitizer merge, but RM should > >> likely > >> approve it: Richi, Jakub, do you support it? > > > > Could you please prepare a patch, so that we can see how much actually > > changed and decide based on that whether to go for a merge or cherry-picking > > one or more commits? > > Sure, there it is. There's a minor change in output format that I address in > 0003 patch. > > Apart from that, I was able to run all tests on x86_64-linux-gnu. > Patch statistics: > 46 files changed, 524 insertions(+), 252 deletions(-) > > I'm running build on ppc64le and if you're fine, I'm going to finish > a proper libsanitizer testing procedure. Ok. Jakub
libsanitizer: sync from master
Hi. I've just pushed libsanitizer update that was tested on x86_64-linux and ppc64le-linux systems. Moreover, I run bootstrap on x86_64-linux and checked ABI difference with abidiff. Pushed as r13-4068-g3037f11fb86eda. Cheers, Martin
[PATCH] Fortran: ICE in simplification of array expression involving power [PR107680]
Dear all, when constant expressions involve parentheses, array constructors, typespecs, and the power operator (**), we could fail with an ICE during simplification in arith_power. Debugging of the testcase showed we call the proper type conversions needed for the arithmetic operation, but under certain circumstances we seem to lose the typespec on the way to the invocation of the simplification. We then run into unhandled combinations of operand types. The attached patch is likely a sort of a band-aid to the problem: we check the operand types in arith_power, and if we see that a conversion is (still) needed, we punt and defer the simplification. AFAICT this is safe. It does not address a possibly deeply covered issue in gfortran, which was suspected when analyzing pr107000. But as this is elusive, that may be hard to locate and fix. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald From efe9dafabc2e2cc2dab079dfa3be3d09b3471c0f Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Tue, 15 Nov 2022 21:20:20 +0100 Subject: [PATCH] Fortran: ICE in simplification of array expression involving power [PR107680] gcc/fortran/ChangeLog: PR fortran/107680 * arith.cc (arith_power): Check that operands are properly converted before attempting to simplify. gcc/testsuite/ChangeLog: PR fortran/107680 * gfortran.dg/pr107680.f90: New test. --- gcc/fortran/arith.cc | 7 ++ gcc/testsuite/gfortran.dg/pr107680.f90 | 34 ++ 2 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr107680.f90 diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc index fc9224ebc5c..c4ab75b401c 100644 --- a/gcc/fortran/arith.cc +++ b/gcc/fortran/arith.cc @@ -845,6 +845,13 @@ arith_power (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) if (!gfc_numeric_ts (&op1->ts) || !gfc_numeric_ts (&op2->ts)) return ARITH_INVALID_TYPE; + /* The result type is derived from op1 and must be compatible with the + result of the simplification. Otherwise postpone simplification until + after operand conversions usually done by gfc_type_convert_binary. */ + if ((op1->ts.type == BT_INTEGER && op2->ts.type != BT_INTEGER) + || (op1->ts.type == BT_REAL && op2->ts.type == BT_COMPLEX)) +return ARITH_NOT_REDUCED; + rc = ARITH_OK; result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); diff --git a/gcc/testsuite/gfortran.dg/pr107680.f90 b/gcc/testsuite/gfortran.dg/pr107680.f90 new file mode 100644 index 000..4ed431eb06f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr107680.f90 @@ -0,0 +1,34 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! PR fortran/107680 - ICE in arith_power +! Contributed by G.Steinmetz + +program p + real,parameter :: x(*) = [real:: ([1])] ** 2.0 + complex, parameter :: y(*) = [real:: ([1])] ** (2.0,1.0) + complex, parameter :: z(*) = [complex :: ([1])] ** (2.0,1.0) + complex, parameter :: u(*) = [complex :: ([1.0])] ** (2.0,1.0) + complex, parameter :: v(*) = [real:: ([(1.0,2.0)])] ** (3.0,1.0) + complex, parameter :: w(*) = [integer :: ([(1.0,2.0)])] ** (3.0,1.0) + print *, [real:: ([3])] ** 2 + print *, [real:: ([3])] ** 2.0 + print *, [real:: ([1])] ** (1.0,2.0) + print *, [real:: ([1.0])] ** (1.0,2.0) + print *, [complex :: ([3])] ** 2 + print *, [complex :: ([3])] ** 2.0 + print *, [complex :: ([1])] ** (1.0,2.0) + print *, [complex :: ([1.0])] ** (1.0,2.0) + print *, [integer :: ([3.0])] ** 2 + print *, [integer :: ([3.0])] ** 2.0 + print *, [integer :: ([1.0])] ** (1.0,2.0) + print *, [integer :: ([(1.0,2.0)])] ** (3.0,1.0) + print *, v(1) + if (u(1) /= 1) stop 1 + if (v(1) /= 1) stop 2 + if (w(1) /= 1) stop 3 + if (x(1) /= 1) stop 4 + if (y(1) /= 1) stop 5 + if (z(1) /= 1) stop 6 +end + +! { dg-final { scan-tree-dump-not "_gfortran_stop_numeric" "original" } } -- 2.35.3
Re: [PATCH 2/5] c++: Set the locus of the function result decl
On 11/12/22 13:45, Bernhard Reutner-Fischer wrote: gcc/cp/ChangeLog: * decl.cc (start_function): Set the result decl source location to the location of the typespec. --- Bootstrapped and regtested on x86_86-unknown-linux with no regressions. Ok for trunk? Cc: Nathan Sidwell Cc: Jason Merrill --- gcc/cp/decl.cc | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 6e98ea35a39..ed40815e645 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -17449,6 +17449,8 @@ start_function (cp_decl_specifier_seq *declspecs, tree attrs) { tree decl1; + tree result; + bool ret; We now prefer to declare new variables as late as possible, usually when they are initialized. decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs); invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1); @@ -17461,7 +17463,18 @@ start_function (cp_decl_specifier_seq *declspecs, gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node)); - return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); + ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); + + /* decl1 might be ggc_freed here. */ + decl1 = current_function_decl; + + /* Set the result decl source location to the location of the typespec. */ + if (TREE_CODE (decl1) == FUNCTION_DECL + && declspecs->locations[ds_type_spec] != UNKNOWN_LOCATION + && (result = DECL_RESULT (decl1)) != NULL_TREE + && DECL_SOURCE_LOCATION (result) == input_location) +DECL_SOURCE_LOCATION (result) = declspecs->locations[ds_type_spec]; One way to handle the template case would be for the code in start_preparsed_function that sets DECL_RESULT to check whether decl1 is a template instantiation, and in that case copy the location from the template's DECL_RESULT, i.e. DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))) + return ret; } /* Returns true iff an EH_SPEC_BLOCK should be created in the body of
Re: [PATCH v3 2/3] libcpp: add a function to determine UTF-8 validity of a C string
On 11/8/22 16:10, Ben Boeckel wrote: This simplifies the interface for other UTF-8 validity detections when a simple "yes" or "no" answer is sufficient. libcpp/ * charset.cc: Add `_cpp_valid_utf8_str` which determines whether a C string is valid UTF-8 or not. * internal.h: Add prototype for `_cpp_valid_utf8_str`. Signed-off-by: Ben Boeckel --- libcpp/charset.cc | 20 libcpp/internal.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/libcpp/charset.cc b/libcpp/charset.cc index 324b5b19136..e130bc01f48 100644 --- a/libcpp/charset.cc +++ b/libcpp/charset.cc @@ -1868,6 +1868,26 @@ _cpp_valid_utf8 (cpp_reader *pfile, return true; } +/* Detect whether a C-string is a valid UTF-8-encoded set of bytes. Returns +`false` if any contained byte sequence encodes an invalid Unicode codepoint +or is not a valid UTF-8 sequence. Returns `true` otherwise. */ + +extern bool +_cpp_valid_utf8_str (const char *name) +{ + const uchar* in = (const uchar*)name; + size_t len = strlen(name); You'se missing a space before (. + cppchar_t cp; + + while (*in) +{ + if (one_utf8_to_cppchar(&in, &len, &cp)) Here too. OK with those fixed. + return false; +} + + return true; +} + /* Subroutine of convert_hex and convert_oct. N is the representation in the execution character set of a numeric escape; write it into the string buffer TBUF and update the end-of-string pointer therein. WIDE diff --git a/libcpp/internal.h b/libcpp/internal.h index badfd1b40da..4f2dd4a2f5c 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -834,6 +834,8 @@ extern bool _cpp_valid_utf8 (cpp_reader *pfile, struct normalize_state *nst, cppchar_t *cp); +extern bool _cpp_valid_utf8_str (const char *str); + extern void _cpp_destroy_iconv (cpp_reader *); extern unsigned char *_cpp_convert_input (cpp_reader *, const char *, unsigned char *, size_t, size_t,
Re: [PATCH v3 1/3] libcpp: reject codepoints above 0x10FFFF
On 11/8/22 16:10, Ben Boeckel wrote: Unicode does not support such values because they are unrepresentable in UTF-16. libcpp/ * charset.cc: Reject encodings of codepoints above 0x10. UTF-16 does not support such codepoints and therefore all Unicode rejects such values. OK. Signed-off-by: Ben Boeckel --- libcpp/charset.cc | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libcpp/charset.cc b/libcpp/charset.cc index 12a398e7527..324b5b19136 100644 --- a/libcpp/charset.cc +++ b/libcpp/charset.cc @@ -158,6 +158,10 @@ struct _cpp_strbuf encoded as any of DF 80, E0 9F 80, F0 80 9F 80, F8 80 80 9F 80, or FC 80 80 80 9F 80. Only the first is valid. + Additionally, Unicode declares that all codepoints above 0010 are + invalid because they cannot be represented in UTF-16. As such, all 5- and + 6-byte encodings are invalid. + An implementation note: the transformation from UTF-16 to UTF-8, or vice versa, is easiest done by using UTF-32 as an intermediary. */ @@ -216,7 +220,7 @@ one_utf8_to_cppchar (const uchar **inbufp, size_t *inbytesleftp, if (c <= 0x3FF && nbytes > 5) return EILSEQ; /* Make sure the character is valid. */ - if (c > 0x7FFF || (c >= 0xD800 && c <= 0xDFFF)) return EILSEQ; + if (c > 0x10 || (c >= 0xD800 && c <= 0xDFFF)) return EILSEQ; *cp = c; *inbufp = inbuf; @@ -320,7 +324,7 @@ one_utf32_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, s += inbuf[bigend ? 2 : 1] << 8; s += inbuf[bigend ? 3 : 0]; - if (s >= 0x7FFF || (s >= 0xD800 && s <= 0xDFFF)) + if (s > 0x10 || (s >= 0xD800 && s <= 0xDFFF)) return EILSEQ; rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp);
typespec in forall and implied-do
F2008 introduced the inclusion of a typespec in a forall statement, and thn F2018 a typespec was allowed in an implied-do. There may even be a few bug reports. Consider, program foo implicit none integer, parameter :: n = 9 integer a(n,n), b(n), j b = [(k, integer :: k = 1, n)] if (any(b /= [1, 2, 3, 4, 5, 6, 7, 8, 9])) stop 1 a = 0 forall (integer :: i = 1:n) a(i,i) = b(i) do j = 1, n if (a(j,j) /= b(j)) stop j end do call bar contains subroutine bar real x(n) x = [(sqrt(real(p)), integer :: p = 1, n)] print '(*(F8.2,1X))', x end subroutine bar end program foo This patch allows the above to compile and execute. It has only had some light testing, and I do not know if nested forall and implied-do loops do work. Feel free to commit as I cannot. diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc index 8b8b6e79c8b..3fd2a80caad 100644 --- a/gcc/fortran/match.cc +++ b/gcc/fortran/match.cc @@ -968,9 +968,39 @@ gfc_match_iterator (gfc_iterator *iter, int init_flag) gfc_expr *var, *e1, *e2, *e3; locus start; match m; + gfc_typespec ts; + bool seen_ts; e1 = e2 = e3 = NULL; + /* Match an optional "integer ::" type-spec. */ + start = gfc_current_locus; + seen_ts = false; + gfc_clear_ts (&ts); + m = gfc_match_type_spec (&ts); + if (m == MATCH_YES) +{ + seen_ts = (gfc_match (" ::") == MATCH_YES); + + if (seen_ts) + { + if (!gfc_notify_std (GFC_STD_F2018, "Optional type-spec " + "included in implied-do loop at %C")) + goto cleanup; + + if (ts.type != BT_INTEGER) + { + gfc_error ("Type in type-spec at %C shall be INTEGER"); + goto cleanup; + } + } +} + else if (m == MATCH_ERROR) +goto cleanup; + + if (!seen_ts) +gfc_current_locus = start; + /* Match the start of an iterator without affecting the symbol table. */ start = gfc_current_locus; @@ -984,6 +1014,14 @@ gfc_match_iterator (gfc_iterator *iter, int init_flag) if (m != MATCH_YES) return MATCH_NO; + if (seen_ts && var->ts.type == BT_UNKNOWN) +{ + var->ts.type = ts.type; + var->ts.kind = ts.kind; + var->symtree->n.sym->ts.type = ts.type; + var->symtree->n.sym->ts.kind = ts.kind; +} + if (var->symtree->n.sym->attr.dimension) { gfc_error ("Loop variable at %C cannot be an array"); @@ -2396,6 +2434,9 @@ match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask) gfc_forall_iterator *head, *tail, *new_iter; gfc_expr *msk; match m; + locus start; + gfc_typespec ts; + bool seen_ts; gfc_gobble_whitespace (); @@ -2405,12 +2446,48 @@ match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask) if (gfc_match_char ('(') != MATCH_YES) return MATCH_NO; + /* Match an optional "integer ::" type-spec. */ + start = gfc_current_locus; + seen_ts = false; + gfc_clear_ts (&ts); + m = gfc_match_type_spec (&ts); + if (m == MATCH_YES) +{ + seen_ts = (gfc_match (" ::") == MATCH_YES); + + if (seen_ts) + { + if (!gfc_notify_std (GFC_STD_F2008, "Optional type-spec " + "included in FORALL at %C")) + goto cleanup; + + if (ts.type != BT_INTEGER) + { + gfc_error ("Type in type-spec at %C shall be INTEGER"); + goto cleanup; + } + } +} + else if (m == MATCH_ERROR) +goto cleanup; + + if (!seen_ts) +gfc_current_locus = start; + m = match_forall_iterator (&new_iter); if (m == MATCH_ERROR) goto cleanup; if (m == MATCH_NO) goto syntax; + if (seen_ts && new_iter->var->ts.type == BT_UNKNOWN) +{ + new_iter->var->ts.type = ts.type; + new_iter->var->ts.kind = ts.kind; + new_iter->var->symtree->n.sym->ts.type = ts.type; + new_iter->var->symtree->n.sym->ts.kind = ts.kind; +} + head = tail = new_iter; for (;;)
Re: typespec in forall and implied-do
On Tue, Nov 15, 2022 at 05:13:19PM -0800, Steve Kargl via Fortran wrote: > F2008 introduced the inclusion of a typespec in a forall > statement, and thn F2018 a typespec was allowed in an > implied-do. There may even be a few bug reports. > Forgot to ask. Anyone know how namespaces work with initialization expressions in gfortran? This code should compile program foo use iso_fortran_env, only : k => real_kinds implicit none integer, parameter :: n = size(k) integer, parameter :: & & p(n) = [(precision(real(1.,k(i))), integer :: i = 1, n)] print '(*(I0,X))', p end program foo The first occurence of 'i' in the expression for 'p(n)' is either thought to be in a different namespace, or an implied-do loop cannot be used in an initialization expression. -- Steve