jhuber6 created this revision. jhuber6 added reviewers: jdoerfert, JonChesterfield, tra, jyknight, MaskRay, yaxunl, aaron.ballman, ronlieb. Herald added a subscriber: StephenFan. Herald added a project: All. jhuber6 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The offloading toolchain makes heavy use of options beginning with `--o`. This is problematic when combined with the joined `-o` flag. In the following situation, the user will not get the expected output and will not notice as the expected output will still be written. clang++ -x cuda foo.cu -offload-arch=sm_80 -o foo This patch introduces a warning that checks for joined `-o` arguments that would also be a valid driver argument if an additional `-` were added. I believe this situation is uncommon enough to warrant a warning, and can be trivially fixed by the end user by using the more common separate form instead. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D135389 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/lib/Driver/Driver.cpp clang/test/Driver/unknown-arg.c Index: clang/test/Driver/unknown-arg.c =================================================================== --- clang/test/Driver/unknown-arg.c +++ clang/test/Driver/unknown-arg.c @@ -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 -output -o foo \ +// RUN: %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'? Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ 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. + auto ArgString = A->getAsString(Args); + std::string Nearest; + if (getOpts().findNearest("-" + ArgString, Nearest, IncludedFlagsBitmask, + ExcludedFlagsBitmask) == 1) + Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument) + << ArgString << Nearest; + } + return Args; } Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ 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<ClangClPch>; +def warn_drv_potentially_misspelled_joined_argument : Warning< + "joined argument treated as '%0'; did you mean '%1'?">, InGroup<UnknownArgument>; + 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<
Index: clang/test/Driver/unknown-arg.c =================================================================== --- clang/test/Driver/unknown-arg.c +++ clang/test/Driver/unknown-arg.c @@ -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 -output -o foo \ +// RUN: %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'? Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ 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. + auto ArgString = A->getAsString(Args); + std::string Nearest; + if (getOpts().findNearest("-" + ArgString, Nearest, IncludedFlagsBitmask, + ExcludedFlagsBitmask) == 1) + Diags.Report(diag::warn_drv_potentially_misspelled_joined_argument) + << ArgString << Nearest; + } + return Args; } Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ 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<ClangClPch>; +def warn_drv_potentially_misspelled_joined_argument : Warning< + "joined argument treated as '%0'; did you mean '%1'?">, InGroup<UnknownArgument>; + 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<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits