diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -253,6 +253,9 @@ "support for '/Yc' with more than one source file not implemented yet; flag ignored">, InGroup; +def warn_drv_potentially_misspelled_joined_argument : Warning< + "joined argument treated as '%0'; did you mean '%1'?">, InGroup; + def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">; def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; def err_drv_invalid_value_with_suggestion : Error< diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -327,6 +327,19 @@ DiagnosticsEngine::Warning; } + for (const Arg *A : Args.filtered(options::OPT_o)) { + if (ArgStrings[A->getIndex()] == A->getSpelling()) + continue; + + // Warn on joined arguments that are similar to a long argument. + std::string ArgString = ArgStrings[A->getIndex()]; + std::string Nearest; + if (getOpts().findNearest("-" + ArgString, Nearest, IncludedFlagsBitmask, + ExcludedFlagsBitmask) == 0) + Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument) + << A->getAsString(Args) << Nearest; + } + return Args; } diff --git a/clang/test/Driver/unknown-arg.c b/clang/test/Driver/unknown-arg.c --- a/clang/test/Driver/unknown-arg.c +++ b/clang/test/Driver/unknown-arg.c @@ -1,5 +1,5 @@ -// RUN: not %clang %s -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -ifoo -imultilib dir -### 2>&1 | \ -// RUN: FileCheck %s +// RUN: not %clang %s -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -ifoo -imultilib dir -o ffload-device-only -### 2>&1 | \ +// RUN: FileCheck %s --implicit-check-not=warning: // RUN: %clang %s -imultilib dir -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=MULTILIB // RUN: not %clang %s -stdlibs=foo -hell -version -### 2>&1 | \ @@ -64,3 +64,9 @@ // RUN: %clang -S %s -o %t.s -Wunknown-to-clang-option 2>&1 | FileCheck --check-prefix=IGNORED %s // IGNORED: warning: unknown warning option '-Wunknown-to-clang-option' + +// RUN: %clang -### -offload-arch=sm_70 --offload-arch=sm_70 -offload-device-only -o ffload-device-only \ +// RUN: -output -o foo %s 2>&1 | FileCheck --check-prefix=O-WARN %s +// O-WARN: warning: joined argument treated as '-o ffload-arch=sm_70'; did you mean '--offload-arch=sm_70'? +// O-WARN-NEXT: warning: joined argument treated as '-o ffload-device-only'; did you mean '--offload-device-only'? +// O-WARN-NEXT: warning: joined argument treated as '-o utput'; did you mean '--output'?