Hi all, when looking into 94690, I was wondering why it didn't accept 'collapse(2)'. Well, it turned out that the line was too long and the string got clipped.
There is a nice check whether a comment is a real comment or an OpenACC/OpenMP directive or an !GCC$ attribute – but this check in gfc_next_char_literal comes too late – as the string is already truncated and the truncated flag is not set. The problem is that load_line sets 'seen_comment' and if it is true, it does not set the truncated flag (used by gfc_next_char_literal and used in load_line to do <tab> usage diagostic). This patch unsets the seen_comment when the first comment is (case insensitive) '!$' (-fopenmp), '!$acc' (-fopenacc) or '!GCC$' [or c/* in the first column with fixed-form source code]. !$ is needed for OpenMP's conditional compilation sentinel; there is some complicated fine print – but as this only affects <tab> diagnostic, it is not worthwhile to spend efford on it. [For truncation, there is an extra check in gfc_next_char_literal which ensures that !$acc is not diagnosed with -fopenmp -fno-openacc.] OK for the trunk? Tobias ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
[Fortran] Truncate warn with OpenMP/OpenACC/!GCC$ (PR94709) While '!$' with -fopenmp unsets too often load_line's seen_comment flag, this only affects <tab> warnings; for trunction warnings, gfc_next_char_literal re-handles the directives correctly. In terms of missed warnings, a directive that is completely in the truncated part is not diagnosted (as it starts with a '!'). PR fortran/94709 * scanner.c (load_line): In fixed form, also tread 'C' as comment and 'D'/'d' only with -fd-lines-as-comments. Treat '!$' with -fopenmp, '!$acc' with -fopenacc and '!GCC$' as non-comment to permit <tab> and truncation warnings. PR fortran/94709 * gfortran.dg/gomp/warn_truncated.f: New. * gfortran.dg/gomp/warn_truncated.f90: New. gcc/fortran/scanner.c | 57 ++++++++++++++++++----- gcc/testsuite/gfortran.dg/gomp/warn_truncated.f | 15 ++++++ gcc/testsuite/gfortran.dg/gomp/warn_truncated.f90 | 19 ++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c index f65594f8baa..6f93508f934 100644 --- a/gcc/fortran/scanner.c +++ b/gcc/fortran/scanner.c @@ -1755,11 +1755,15 @@ static int load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char) { int c, maxlen, i, preprocessor_flag, buflen = *pbuflen; - int trunc_flag = 0, seen_comment = 0; - int seen_printable = 0, seen_ampersand = 0, quoted = ' '; - gfc_char_t *buffer; + int quoted = ' ', comment_ix = -1; + bool seen_comment = false; + bool first_comment = true; + bool trunc_flag = false; + bool seen_printable = false; + bool seen_ampersand = false; bool found_tab = false; bool warned_tabs = false; + gfc_char_t *buffer; /* Determine the maximum allowed line length. */ if (gfc_current_form == FORM_FREE) @@ -1794,7 +1798,7 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char) /* In order to not truncate preprocessor lines, we have to remember that this is one. */ - preprocessor_flag = (c == '#' ? 1 : 0); + preprocessor_flag = (c == '#'); for (;;) { @@ -1824,20 +1828,24 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char) { if (seen_ampersand) { - seen_ampersand = 0; - seen_printable = 1; + seen_ampersand = false; + seen_printable = true; } else - seen_ampersand = 1; + seen_ampersand = true; } if ((c != '&' && c != '!' && c != ' ') || (c == '!' && !seen_ampersand)) - seen_printable = 1; + seen_printable = true; /* Is this a fixed-form comment? */ if (gfc_current_form == FORM_FIXED && i == 0 - && (c == '*' || c == 'c' || c == 'd')) - seen_comment = 1; + && (c == '*' || c == 'c' || c == 'C' + || (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D')))) + { + seen_comment = true; + comment_ix = i; + } if (quoted == ' ') { @@ -1849,7 +1857,34 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char) /* Is this a free-form comment? */ if (c == '!' && quoted == ' ') - seen_comment = 1; + { + if (seen_comment) + first_comment = false; + seen_comment = true; + comment_ix = i; + } + + /* For truncation and tab warnings, set seen_comment to false if one has + either an OpenMP or OpenACC directive - or a !GCC$ attribute. If + OpenMP is enabled, use '!$' as as conditional compilation sentinel + and OpenMP directive ('!$omp'). */ + if (seen_comment && first_comment && flag_openmp && comment_ix + 1 == i + && c == '$') + first_comment = seen_comment = false; + if (seen_comment && first_comment && comment_ix + 4 == i) + { + if (((*pbuf)[comment_ix+1] == 'g' || (*pbuf)[comment_ix+1] == 'G') + && ((*pbuf)[comment_ix+2] == 'c' || (*pbuf)[comment_ix+2] == 'C') + && ((*pbuf)[comment_ix+3] == 'c' || (*pbuf)[comment_ix+3] == 'C') + && (*pbuf)[comment_ix+4] == '$') + first_comment = seen_comment = false; + if (flag_openacc + && (*pbuf)[comment_ix+1] == '$' + && ((*pbuf)[comment_ix+2] == 'a' || (*pbuf)[comment_ix+2] == 'A') + && ((*pbuf)[comment_ix+3] == 'c' || (*pbuf)[comment_ix+3] == 'C') + && ((*pbuf)[comment_ix+4] == 'c' || (*pbuf)[comment_ix+4] == 'C')) + first_comment = seen_comment = false; + } /* Vendor extension: "<tab>1" marks a continuation line. */ if (found_tab) diff --git a/gcc/testsuite/gfortran.dg/gomp/warn_truncated.f b/gcc/testsuite/gfortran.dg/gomp/warn_truncated.f new file mode 100644 index 00000000000..5b50b8ad843 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/warn_truncated.f @@ -0,0 +1,15 @@ +! { dg-do compile } +! { dg-additional-options "-Wall" } +! +! PR fortran/94709 +! +! Check that 'Line truncated' gets printed as appropriate +! +c$omp target ! map() +c$omp end target + +c$omp target map() ! { dg-warning "Line truncated" } +c$acc declare map() +ca = 5 +c$omp end target + end diff --git a/gcc/testsuite/gfortran.dg/gomp/warn_truncated.f90 b/gcc/testsuite/gfortran.dg/gomp/warn_truncated.f90 new file mode 100644 index 00000000000..86d7eb27b30 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/warn_truncated.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! +! PR fortran/94709 +! +! Check that 'Line truncated' gets printed as appropriate +! +integer i +i = 0 +!$omp target ! map() +!$omp end target + +!$omp target map() ! { dg-error "Line truncated" } +!$acc kernels copy() +!a = 5 +!$acc end kernels +!$omp end target +end + +! { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 }