aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/scanner.c
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2021-09-21 08:27:00 +0200
committerTobias Burnus <tobias@codesourcery.com>2021-09-21 08:28:30 +0200
commit417ea5c02cef7f000e66d1af22b066c2c1cda047 (patch)
tree1212ed64ad39e507f11d767384a56c08136a7d36 /gcc/fortran/scanner.c
parent63c6446f77b9001d26f973114450d790749f282b (diff)
downloadgcc-417ea5c02cef7f000e66d1af22b066c2c1cda047.zip
gcc-417ea5c02cef7f000e66d1af22b066c2c1cda047.tar.gz
gcc-417ea5c02cef7f000e66d1af22b066c2c1cda047.tar.bz2
Fortran: Fix -Wno-missing-include-dirs handling [PR55534]
gcc/fortran/ChangeLog: PR fortran/55534 * cpp.c: Define GCC_C_COMMON_C for #include "options.h" to make cpp_reason_option_codes available. (gfc_cpp_register_include_paths): Make static, set pfile's warn_missing_include_dirs and move before caller. (gfc_cpp_init_cb): New, cb code moved from ... (gfc_cpp_init_0): ... here. (gfc_cpp_post_options): Call gfc_cpp_init_cb. (cb_cpp_diagnostic_cpp_option): New. As implemented in c-family to match CppReason flags to -W... names. (cb_cpp_diagnostic): Use it to replace single special case. * cpp.h (gfc_cpp_register_include_paths): Remove as now static. * gfortran.h (gfc_check_include_dirs): New prototype. (gfc_add_include_path): Add new bool arg. * options.c (gfc_init_options): Don't set -Wmissing-include-dirs. (gfc_post_options): Set it here after commandline processing. Call gfc_add_include_path with defer_warn=false. (gfc_handle_option): Call it with defer_warn=true. * scanner.c (gfc_do_check_include_dir, gfc_do_check_include_dirs, gfc_check_include_dirs): New. Diagnostic moved from ... (add_path_to_list): ... here, which came before cmdline processing. Take additional bool defer_warn argument. (gfc_add_include_path): Take additional defer_warn arg. * scanner.h (struct gfc_directorylist): Reorder for alignment issues, add new 'bool warn'. libgfortran/ChangeLog: PR fortran/55534 * configure.ac (AM_FCFLAGS): Add -Wno-missing-include-dirs. * configure: Regenerate. libgomp/ChangeLog: PR fortran/55534 * testsuite/libgomp.fortran/fortran.exp: Add -Wno-missing-include-dirs to ALWAYS_CFLAGS. * testsuite/libgomp.oacc-fortran/fortran.exp: Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/include_6.f90: Change dg-error to dg-warning and update pattern. * gfortran.dg/include_14.f90: New test. * gfortran.dg/include_15.f90: New test. * gfortran.dg/include_16.f90: New test. * gfortran.dg/include_17.f90: New test. * gfortran.dg/include_18.f90: New test. * gfortran.dg/include_19.f90: New test. * gfortran.dg/include_20.f90: New test. * gfortran.dg/include_21.f90: New test.
Diffstat (limited to 'gcc/fortran/scanner.c')
-rw-r--r--gcc/fortran/scanner.c82
1 files changed, 62 insertions, 20 deletions
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 39db099..6fe74bd 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -298,17 +298,69 @@ gfc_scanner_done_1 (void)
}
}
+static bool
+gfc_do_check_include_dir (const char *path, bool warn)
+{
+ struct stat st;
+ if (stat (path, &st))
+ {
+ if (errno != ENOENT)
+ gfc_warning_now (0, "Include directory %qs: %s",
+ path, xstrerror(errno));
+ else if (warn && !gfc_cpp_enabled ())
+ gfc_warning_now (OPT_Wmissing_include_dirs,
+ "Nonexistent include directory %qs", path);
+ return false;
+ }
+ else if (!S_ISDIR (st.st_mode))
+ {
+ gfc_fatal_error ("%qs is not a directory", path);
+ return false;
+ }
+ return true;
+}
+
+/* In order that -W(no-)missing-include-dirs works, the diagnostic can only be
+ run after processing the commandline. */
+static void
+gfc_do_check_include_dirs (gfc_directorylist **list)
+{
+ gfc_directorylist *prev, *q, *n;
+ prev = NULL;
+ n = *list;
+ while (n)
+ {
+ q = n; n = n->next;
+ if (gfc_do_check_include_dir (q->path, q->warn))
+ {
+ prev = q;
+ continue;
+ }
+ if (prev == NULL)
+ *list = n;
+ else
+ prev->next = n;
+ free (q->path);
+ free (q);
+ }
+}
+
+void
+gfc_check_include_dirs ()
+{
+ gfc_do_check_include_dirs (&include_dirs);
+ gfc_do_check_include_dirs (&intrinsic_modules_dirs);
+}
/* Adds path to the list pointed to by list. */
static void
add_path_to_list (gfc_directorylist **list, const char *path,
- bool use_for_modules, bool head, bool warn)
+ bool use_for_modules, bool head, bool warn, bool defer_warn)
{
gfc_directorylist *dir;
const char *p;
char *q;
- struct stat st;
size_t len;
int i;
@@ -326,21 +378,8 @@ add_path_to_list (gfc_directorylist **list, const char *path,
while (i >=0 && IS_DIR_SEPARATOR (q[i]))
q[i--] = '\0';
- if (stat (q, &st))
- {
- if (errno != ENOENT)
- gfc_warning_now (0, "Include directory %qs: %s", path,
- xstrerror(errno));
- else if (warn)
- gfc_warning_now (OPT_Wmissing_include_dirs,
- "Nonexistent include directory %qs", path);
- return;
- }
- else if (!S_ISDIR (st.st_mode))
- {
- gfc_fatal_error ("%qs is not a directory", path);
- return;
- }
+ if (!defer_warn && !gfc_do_check_include_dir (q, warn))
+ return;
if (head || *list == NULL)
{
@@ -362,17 +401,20 @@ add_path_to_list (gfc_directorylist **list, const char *path,
if (head)
*list = dir;
dir->use_for_modules = use_for_modules;
+ dir->warn = warn;
dir->path = XCNEWVEC (char, strlen (p) + 2);
strcpy (dir->path, p);
strcat (dir->path, "/"); /* make '/' last character */
}
+/* defer_warn is set to true while parsing the commandline. */
void
gfc_add_include_path (const char *path, bool use_for_modules, bool file_dir,
- bool warn)
+ bool warn, bool defer_warn)
{
- add_path_to_list (&include_dirs, path, use_for_modules, file_dir, warn);
+ add_path_to_list (&include_dirs, path, use_for_modules, file_dir, warn,
+ defer_warn);
/* For '#include "..."' these directories are automatically searched. */
if (!file_dir)
@@ -383,7 +425,7 @@ gfc_add_include_path (const char *path, bool use_for_modules, bool file_dir,
void
gfc_add_intrinsic_modules_path (const char *path)
{
- add_path_to_list (&intrinsic_modules_dirs, path, true, false, false);
+ add_path_to_list (&intrinsic_modules_dirs, path, true, false, false, false);
}