[PATCH] D99353: [driver] Make `clang` warn rather then error on `flang` options

Andrzej Warzynski via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 25 10:24:40 PDT 2021


awarzynski created this revision.
Herald added a reviewer: sscalpone.
awarzynski requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds extra logic in Driver::ParseArgStrings so that `clang`
(Clang's compiler driver) generates a warning when a Flang-only option
is used. Previously it would throw an error:

- `error: unknown argument: <option>`

and exit immediately. That was flagged as problematic in [1].

The new behaviour is consistent with GCC:

  gcc -c  -ffree-form  file.c
  cc1: warning: command line option ‘-ffree-form’ is valid for Fortran but not for C

It allows users to use `clang` as e.g. a linker driver, without worrying
about passing Fortran specific flags to `clang`. These flags are often
embedded in build systems and are hard to extract just for linking.
An issue like this raised in [1]. This patch is an attempt to address
this.

The current approach is a bit verbose. Ideally we should extend the
OptTable API to make accommodating for situations like this easier. In
particular, I'm not sure whether we can add similar logic for Flang.
In this patch we are relying on the `FlangOnlyOption` flag to
identify problematic options. There's no equivalent flag for Clang-only
options. I propose that we address this later, when this becomes a
problem for Flang.

[1] https://reviews.llvm.org/D95460


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D99353

Files:
  clang/lib/Driver/Driver.cpp


Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -223,7 +223,6 @@
   InputArgList Args =
       getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount,
                           IncludedFlagsBitmask, ExcludedFlagsBitmask);
-
   // Check for missing argument error.
   if (MissingArgCount) {
     Diag(diag::err_drv_missing_argument)
@@ -263,20 +262,43 @@
   }
 
   for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
-    unsigned DiagID;
+    // The default diagnostic when the option is unknow
+    unsigned DiagID = diag::err_drv_unknown_argument;
+
+    // Try to find a good hint for the user
     auto ArgString = A->getAsString(Args);
     std::string Nearest;
-    if (getOpts().findNearest(
-          ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) > 1) {
-      DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
-                          : diag::err_drv_unknown_argument;
-      Diags.Report(DiagID) << ArgString;
-    } else {
+    unsigned Distance = getOpts().findNearest(
+        ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask);
+    assert(Distance != 0 && "This option should not be 'unknown'");
+
+    if (Distance == 1) {
+      // Found a good suggestion - propose that in the diagnostic
       DiagID = IsCLMode()
                    ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
                    : diag::err_drv_unknown_argument_with_suggestion;
       Diags.Report(DiagID) << ArgString << Nearest;
+    } else {
+      // No good suggestion was found - the diagnostic depends on the mode in
+      // which the driver operates
+      if (IsCLMode())
+        // In CL mode just warn the user (MSVC consumes everything anyway)
+        DiagID = diag::warn_drv_unknown_argument_clang_cl;
+      else if (!IsFlangMode()) {
+        // In non-Flang mode, check whether this is a Flang flag and
+        // communicate accordingly.
+        ExcludedFlagsBitmask &= ~options::FlangOnlyOption;
+        if (getOpts().findNearest(ArgString, Nearest, IncludedFlagsBitmask,
+                                  ExcludedFlagsBitmask) == 0)
+          DiagID =
+              Diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
+                                    "command line option ‘%0’ is only valid "
+                                    "in Flang mode (i.e. for Fortran input)");
+      } // TODO: Check whether this is a C-mode flag and report accordingly.
+
+      Diags.Report(DiagID) << ArgString;
     }
+
     ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) >
                      DiagnosticsEngine::Warning;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D99353.333340.patch
Type: text/x-patch
Size: 2768 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210325/e2744603/attachment.bin>


More information about the cfe-commits mailing list