Hi Harald,
On 22.09.21 20:29, Harald Anlauf via Gcc-patches wrote:
> What I find a bit confusing - from the viewpoint of a user - is the
> case of using the preprocessor (-cpp), as one gets e.g.
>
> <built-in>: Warning: ./no/such/dir: No such file or directory
> [-Wmissing-include-dirs]
>
> while without -cpp:
>
> f951: Warning: Nonexistent include directory './no/such/dir/'
> [-Wmissing-include-dirs]
C/C++ do something likewise (grep for that string).
The reason for the <built-in> is the code in cpp.c's gfc_cpp_init,
which uses:
cpp_change_file (cpp_in, LC_RENAME, _("<built-in>"));
It might be possible to reset it by passing NULL to it, at the end
of that function but I don't know whether that causes side effects.
At least linemap_add then uses set->depth--.
It might work just fine, but I do not know.
(Additionally, cb_file_change or print_line needs to be updated
to handle to_file == NULL.)
Feel free to experiment there. Otherwise, I leave it as is.
* * *
However, this patch now improves the diagnostic printed by
load_file – and uses directly an fatal error instead of
a usual error and then propagating the error through.
Errors are now also properly colored.
Note:
* -fpre-included= is not easily testable. It works when calling
the compiler itself (f951) but the driver (gfortran) overrides
it here with:
-fpre-include=/usr/include/finclude/math-vector-fortran.h
which exits.
* I did not include the test "include_22.f90" with:
include "include_22.f90" ! { dg-error "File 'include_22.f90' is being included recursively" }
as the error message seemingly confused DejaGNU and causes it
to enter an endless loop.
OK for mainline?
Tobias
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
Fortran: Improve file-reading error diagnostic [PR55534]
PR fortran/55534
gcc/fortran/ChangeLog:
* scanner.c (load_file): Return void, call (gfc_)fatal_error for
all errors.
(include_line, include_stmt, gfc_new_file): Remove exit call
for failed load_file run.
gcc/testsuite/ChangeLog:
* gfortran.dg/include_9.f90: Add dg-prune-output.
* gfortran.dg/include_23.f90: New test.
* gfortran.dg/include_24.f90: New test.
gcc/fortran/scanner.c | 66 ++++++++++++--------------------
gcc/testsuite/gfortran.dg/include_23.f90 | 4 ++
gcc/testsuite/gfortran.dg/include_24.f90 | 4 ++
gcc/testsuite/gfortran.dg/include_9.f90 | 1 +
4 files changed, 33 insertions(+), 42 deletions(-)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "toplev.h" /* For set_src_pwd. */
#include "debug.h"
#include "options.h"
+#include "diagnostic-core.h" /* For fatal_error. */
#include "cpp.h"
#include "scanner.h"
@@ -2230,7 +2231,7 @@ preprocessor_line (gfc_char_t *c)
}
-static bool load_file (const char *, const char *, bool);
+static void load_file (const char *, const char *, bool);
/* include_line()-- Checks a line buffer to see if it is an include
line. If so, we call load_file() recursively to load the included
@@ -2396,9 +2397,7 @@ include_line (gfc_char_t *line)
read by anything else. */
filename = gfc_widechar_to_char (begin, -1);
- if (!load_file (filename, NULL, false))
- exit (FATAL_EXIT_CODE);
-
+ load_file (filename, NULL, false);
free (filename);
return 1;
}
@@ -2505,9 +2504,7 @@ include_stmt (gfc_linebuf *b)
filename[i] = (unsigned char) c;
}
filename[length] = '\0';
- if (!load_file (filename, NULL, false))
- exit (FATAL_EXIT_CODE);
-
+ load_file (filename, NULL, false);
free (filename);
do_ret:
@@ -2525,9 +2522,11 @@ do_ret:
return ret;
}
+
+
/* Load a file into memory by calling load_line until the file ends. */
-static bool
+static void
load_file (const char *realfilename, const char *displayedname, bool initial)
{
gfc_char_t *line;
@@ -2549,13 +2548,8 @@ load_file (const char *realfilename, const char *displayedname, bool initial)
for (f = current_file; f; f = f->up)
if (filename_cmp (filename, f->filename) == 0)
- {
- fprintf (stderr, "%s:%d: Error: File '%s' is being included "
- "recursively\n", current_file->filename, current_file->line,
- filename);
- return false;
- }
-
+ fatal_error (linemap_line_start (line_table, current_file->line, 0),
+ "File %qs is being included recursively", filename);
if (initial)
{
if (gfc_src_file)
@@ -2567,10 +2561,7 @@ load_file (const char *realfilename, const char *displayedname, bool initial)
input = gfc_open_file (realfilename);
if (input == NULL)
- {
- gfc_error_now ("Cannot open file %qs", filename);
- return false;
- }
+ gfc_fatal_error ("Cannot open file %qs", filename);
}
else
{
@@ -2579,22 +2570,20 @@ load_file (const char *realfilename, const char *displayedname, bool initial)
{
/* For -fpre-include file, current_file is NULL. */
if (current_file)
- fprintf (stderr, "%s:%d: Error: Can't open included file '%s'\n",
- current_file->filename, current_file->line, filename);
+ fatal_error (linemap_line_start (line_table, current_file->line, 0),
+ "Cannot open included file %qs", filename);
else
- fprintf (stderr, "Error: Can't open pre-included file '%s'\n",
- filename);
-
- return false;
+ gfc_fatal_error ("Cannot open pre-included file %qs", filename);
}
stat_result = stat (realfilename, &st);
- if (stat_result == 0 && !S_ISREG(st.st_mode))
+ if (stat_result == 0 && !S_ISREG (st.st_mode))
{
- fprintf (stderr, "%s:%d: Error: Included path '%s'"
- " is not a regular file\n",
- current_file->filename, current_file->line, filename);
fclose (input);
- return false;
+ if (current_file)
+ fatal_error (linemap_line_start (line_table, current_file->line, 0),
+ "Included file %qs is not a regular file", filename);
+ else
+ gfc_fatal_error ("Included file %qs is not a regular file", filename);
}
}
@@ -2768,7 +2757,6 @@ load_file (const char *realfilename, const char *displayedname, bool initial)
add_file_change (NULL, current_file->inclusion_line + 1);
current_file = current_file->up;
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
- return true;
}
@@ -2780,23 +2768,17 @@ load_file (const char *realfilename, const char *displayedname, bool initial)
void
gfc_new_file (void)
{
- bool result;
-
- if (flag_pre_include != NULL
- && !load_file (flag_pre_include, NULL, false))
- exit (FATAL_EXIT_CODE);
+ if (flag_pre_include != NULL)
+ load_file (flag_pre_include, NULL, false);
if (gfc_cpp_enabled ())
{
- result = gfc_cpp_preprocess (gfc_source_file);
+ gfc_cpp_preprocess (gfc_source_file);
if (!gfc_cpp_preprocess_only ())
- result = load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
+ load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
}
else
- result = load_file (gfc_source_file, NULL, true);
-
- if (!result)
- exit (FATAL_EXIT_CODE);
+ load_file (gfc_source_file, NULL, true);
gfc_current_locus.lb = line_head;
gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
new file mode 100644
@@ -0,0 +1,4 @@
+implicit none
+include "nonexisting/file.f90" ! { dg-error "Cannot open included file 'nonexisting/file.f90'" }
+end
+! { dg-prune-output "compilation terminated." }
new file mode 100644
@@ -0,0 +1,4 @@
+implicit none
+include "." ! { dg-error "Included file '.' is not a regular file" }
+end
+! { dg-prune-output "compilation terminated." }
@@ -4,3 +4,4 @@
program main
end program
! { dg-error "is not a regular file" " " { target *-*-* } 3 }
+! { dg-prune-output "compilation terminated." }