awarzynski updated this revision to Diff 335270.
awarzynski added a comment.
Herald added subscribers: jansvoboda11, dang.

Refine the behaviour when using diag options and add tests

- `-Werror` will now elevate the warning generated here to an error. This is 
consistent with `gcc`. To this end I had to create a new diagnostic in 
DiagnosticDriverKinds.td.
- Added tests for the logic implemented here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99353/new/

https://reviews.llvm.org/D99353

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/Driver.cpp
  clang/test/Driver/flang-only-option-diags.c
  clang/test/Driver/flang-only-options.c

Index: clang/test/Driver/flang-only-options.c
===================================================================
--- /dev/null
+++ clang/test/Driver/flang-only-options.c
@@ -0,0 +1,70 @@
+// Verifies that Flang options marked as `FlangOnlyOption` are corectly recognised and warned about by Clang.
+//
+// TODO: Add aliases (once working)
+
+// RUN: %clang -fsyntax-only \
+// SKIP:  -Xflang \ This option is currently parsed by Clang as OPT_X_Flang (i.e. `-X flang` rather than `-Xflang`)
+// RUN:   -ffree-form \
+// RUN:   -ffixed-form \
+// RUN:   -module-dir \
+// RUN:   -ffixed-line-length=1 \
+// RUN:   -fopenacc \
+// RUN:   -fdefault-double-8 \
+// RUN:   -fdefault-integer-8 \
+// RUN:   -fdefault-real-8 \
+// RUN:   -flarge-sizes \
+// RUN:   -fbackslash \
+// RUN:   -fno-backslash \
+// RUN:   -fxor-operator \
+// RUN:   -fno-xor-operator \
+// RUN:   -flogical-abbreviations \
+// RUN:   -fno-logical-abbreviations \
+// RUN:   -fimplicit-none \
+// RUN:   -fno-implicit-none \
+// RUN:   -falternative-parameter-statement \
+// RUN:   -fintrinsic-modules-path \
+// RUN:   -test-io \
+// RUN:   -fdebug-unparse \
+// RUN:   -fdebug-unparse-with-symbols \
+// RUN:   -fdebug-dump-symbols \
+// RUN:   -fdebug-dump-parse-tree \
+// RUN:   -fdebug-dump-provenance \
+// RUN:   -fdebug-dump-parsing-log \
+// RUN:   -fdebug-measure-parse-tree \
+// RUN:   -fdebug-pre-fir-tree \
+// RUN:   -fdebug-module-writer \
+// RUN:   -fget-symbols-sources \
+// RUN: %s 2>&1 | FileCheck %s
+
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-ffree-form' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-ffixed-form' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-module-dir' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-ffixed-line-length=1' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fopenacc' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdefault-double-8' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdefault-integer-8' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdefault-real-8' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-flarge-sizes' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fbackslash' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fno-backslash' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fxor-operator' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fno-xor-operator' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-flogical-abbreviations' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fno-logical-abbreviations' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fimplicit-none' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fno-implicit-none' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-falternative-parameter-statement' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fintrinsic-modules-path' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-test-io' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-unparse' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-unparse-with-symbols' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-dump-symbols' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-dump-parse-tree' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-dump-provenance' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-dump-parsing-log' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-measure-parse-tree' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-pre-fir-tree' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fdebug-module-writer' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// CHECK: clang-{{[0-9]+}}: warning: command line option '-fget-symbols-sources' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+
+int a;
Index: clang/test/Driver/flang-only-option-diags.c
===================================================================
--- /dev/null
+++ clang/test/Driver/flang-only-option-diags.c
@@ -0,0 +1,28 @@
+// Test the behaviour of clang with a `FlangOnlyOption` and various diagnostics
+// flags. We want to make sure that users can control whether Flang-only options
+
+// RUN: %clang -fsyntax-only -ffree-form %s 2>&1 | FileCheck %s --check-prefix=WARNING
+// RUN: not %clang -fsyntax-only -Werror -ffree-form %s 2>&1 | FileCheck %s --check-prefix=ERROR
+// RUN: %clang -fsyntax-only -Werror -Wno-unknown-argument -Wno-unused-command-line-argument -ffree-form %s 2>&1 | FileCheck %s --allow-empty --check-prefix=NO-DIAGS
+
+//---------------------------
+// EXPECTED OUTPUT - WARNING
+//---------------------------
+// WARNING: clang-{{[0-9]+}}: warning: command line option '-ffree-form' is only valid in Flang mode (i.e. for Fortran input) [-Wunknown-argument]
+// WARNING-NEXT: clang-{{[0-9]+}}: warning: argument unused during compilation: '-ffree-form' [-Wunused-command-line-argument]
+
+//------------------------
+// EXPECTED OUTPUT - ERROR
+//------------------------
+// ERROR: clang-13: error: command line option '-ffree-form' is only valid in Flang mode (i.e. for Fortran input) [-Werror,-Wunknown-argument]
+
+//---------------------------------
+// EXPECTED OUTPUT - NO DIAGNOSTICS
+//---------------------------------
+// NO-DIAGS-NOT: error
+// NO-DIAGS-NOT: warning
+
+//-------
+// INPUT
+//-------
+int a;
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -222,7 +222,6 @@
   InputArgList Args =
       getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount,
                           IncludedFlagsBitmask, ExcludedFlagsBitmask);
-
   // Check for missing argument error.
   if (MissingArgCount) {
     Diag(diag::err_drv_missing_argument)
@@ -262,20 +261,49 @@
   }
 
   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.
+        unsigned ExcludedFlagsBitmaskWithFlang =
+            ExcludedFlagsBitmask & ~options::FlangOnlyOption;
+
+        unsigned ExpectedDistance = 0;
+        // TODO: This currently doesn't work as information about aliases is
+        // lost when generating "unknown" options.
+        if (auto Alias = A->getAlias())
+          ExpectedDistance = 1;
+
+        if (getOpts().findNearest(ArgString, Nearest, IncludedFlagsBitmask,
+                                  ExcludedFlagsBitmaskWithFlang) ==
+            ExpectedDistance)
+          DiagID = diag::warn_drv_flang_argument;
+      } // TODO: Check whether this is a C-mode flag and report accordingly.
+
+      Diags.Report(DiagID) << ArgString;
     }
+
     ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) >
                      DiagnosticsEngine::Warning;
   }
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4299,10 +4299,7 @@
 //===----------------------------------------------------------------------===//
 // FLangOption + CoreOption + NoXarchOption
 //===----------------------------------------------------------------------===//
-let Flags = [FlangOption, FlangOnlyOption, NoXarchOption, CoreOption] in {
-def Xflang : Separate<["-"], "Xflang">,
-  HelpText<"Pass <arg> to the flang compiler">, MetaVarName<"<arg>">,
-  Flags<[NoXarchOption, CoreOption]>, Group<CompileOnly_Group>;
+let Flags = [FlangOption, FlangOnlyOption, FC1Option] in {
 }
 
 //===----------------------------------------------------------------------===//
@@ -4315,6 +4312,8 @@
   DocBrief<[{This option specifies where to put .mod files for compiled modules.
 It is also added to the list of directories to be searched by an USE statement.
 The default is the current directory.}]>;
+def Xflang : Separate<["-"], "Xflang">,
+  HelpText<"Pass <arg> to the flang compiler">, MetaVarName<"<arg>">;
 
 def ffixed_form : Flag<["-"], "ffixed-form">, Group<f_Group>,
   HelpText<"Process source files in fixed form">;
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -194,6 +194,9 @@
 def err_drv_I_dash_not_supported : Error<
   "'%0' not supported, please use -iquote instead">;
 def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
+def warn_drv_flang_argument : Warning<
+  "command line option '%0' is only valid in Flang mode (i.e. for Fortran input)">,
+  InGroup<UnknownArgument>;
 def err_drv_unknown_argument_with_suggestion : Error<
   "unknown argument '%0'; did you mean '%1'?">;
 def warn_drv_unknown_argument_clang_cl : Warning<
@@ -202,7 +205,6 @@
 def warn_drv_unknown_argument_clang_cl_with_suggestion : Warning<
   "unknown argument ignored in clang-cl '%0'; did you mean '%1'?">,
   InGroup<UnknownArgument>;
-
 def warn_drv_ycyu_different_arg_clang_cl : Warning<
   "support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored">,
   InGroup<ClangClPch>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to