Index: Basic/DiagnosticIDs.cpp =================================================================== --- Basic/DiagnosticIDs.cpp +++ Basic/DiagnosticIDs.cpp @@ -589,9 +589,9 @@ Diags.push_back(StaticDiagInfo[i].DiagID); } -StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor, - StringRef Group) { - StringRef Best; +unsigned DiagnosticIDs::getNearestOption(diag::Flavor Flavor, + StringRef Group, + std::string& NearestOption) { unsigned BestDistance = Group.size() + 1; // Sanity threshold. for (const WarningOption &O : OptionTable) { // Don't suggest ignored warning flags. @@ -609,15 +609,15 @@ if (Distance == BestDistance) { // Two matches with the same distance, don't prefer one over the other. - Best = ""; + NearestOption = ""; } else if (Distance < BestDistance) { // This is a better match. - Best = O.getName(); + NearestOption = O.getName(); BestDistance = Distance; } } - return Best; + return BestDistance; } /// ProcessDiag - This is the method used to report a diagnostic that is Index: Basic/Warnings.cpp =================================================================== --- Basic/Warnings.cpp +++ Basic/Warnings.cpp @@ -30,15 +30,24 @@ #include using namespace clang; +namespace { + constexpr unsigned MaxLevenshteinDistForWarningSuggestion = 2; +} + // EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning // opts static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags, diag::Flavor Flavor, StringRef Prefix, StringRef Opt) { - StringRef Suggestion = DiagnosticIDs::getNearestOption(Flavor, Opt); + std::string Suggestion; + const unsigned OptToSuggestionEditDist + = DiagnosticIDs::getNearestOption(Flavor, Opt, Suggestion); Diags.Report(diag::warn_unknown_diag_option) << (Flavor == diag::Flavor::WarningOrError ? 0 : 1) << (Prefix.str() += Opt) - << !Suggestion.empty() << (Prefix.str() += Suggestion); + << (!Suggestion.empty() + && OptToSuggestionEditDist > 0 + && OptToSuggestionEditDist <= MaxLevenshteinDistForWarningSuggestion) + << (Prefix.str() += Suggestion); } void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, Index: Driver/cc-log-diagnostics.c =================================================================== --- Driver/cc-log-diagnostics.c +++ Driver/cc-log-diagnostics.c @@ -17,7 +17,7 @@ // CHECK: level // CHECK: warning // CHECK: message -// CHECK: unknown warning option '-Wfoobar'; did you mean '-W{{.*}}'? +// CHECK: unknown warning option '-Wfoobar' // CHECK: // CHECK: // CHECK: level Index: Frontend/warning-options.cpp =================================================================== --- Frontend/warning-options.cpp +++ Frontend/warning-options.cpp @@ -3,5 +3,5 @@ // CHECK: unknown warning option '-Wmonkey' // CHECK: unknown warning option '-Wno-monkey' // CHECK: unknown warning option '-Wno-unused-command-line-arguments'; did you mean '-Wno-unused-command-line-argument'? -// CHECK: unknown warning option '-Wmodule-build'; did you mean '-Wmodule-conflict'? +// CHECK: unknown warning option '-Wmodule-build' // CHECK: unknown remark option '-Rmodule-built'; did you mean '-Rmodule-build'? Index: clang/Basic/DiagnosticIDs.h =================================================================== --- clang/Basic/DiagnosticIDs.h +++ clang/Basic/DiagnosticIDs.h @@ -300,8 +300,12 @@ std::vector &Diags); /// Get the diagnostic option with the closest edit distance to the - /// given group name. - static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group); + /// given Group name and return their edit distance. + /// \param [out] NearestOption - The nearest option string found. + /// + /// \return The edit distance between Group and the nearest option found. + static unsigned getNearestOption(diag::Flavor Flavor, StringRef Group, + std::string& NearestOption); private: /// Classify the specified diagnostic ID into a Level, consumable by