diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp --- a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp +++ b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp @@ -623,8 +623,11 @@ PrintfFormatString.size() - PrintfFormatStringPos)); PrintfFormatStringPos = PrintfFormatString.size(); + // It's clearer to convert printf("Hello\r\n"); to std::print("Hello\r\n") + // than to std::println("Hello\r"); if (StringRef(StandardFormatString).ends_with("\\n") && - !StringRef(StandardFormatString).ends_with("\\\\n")) { + !StringRef(StandardFormatString).ends_with("\\\\n") && + !StringRef(StandardFormatString).ends_with("\\r\\n")) { UsePrintNewlineFunction = true; FormatStringNeededRewriting = true; StandardFormatString.erase(StandardFormatString.end() - 2, diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-print.rst @@ -70,8 +70,10 @@ `FprintfLikeFunctions` are replaced with the function specified by the `ReplacementPrintlnFunction` option if the format string ends with ``\n`` or `ReplacementPrintFunction` otherwise. -- the format string is rewritten to use the ``std::formatter`` language and - a ``\n`` is removed from the end. +- the format string is rewritten to use the ``std::formatter`` language. If + a ``\n`` is found at the end of the format string not preceded by ``r`` + then it is removed and `ReplacementPrintlnFunction` is used rather than + `ReplacementPrintFunction`. - any arguments that corresponded to ``%p`` specifiers that ``std::formatter`` wouldn't accept are wrapped in a ``static_cast`` to ``const void *``. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp @@ -44,6 +44,16 @@ // CHECK-FIXES: std::println("Hello"); } +void printf_crlf_newline() { + printf("Hello\r\n"); + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] + // CHECK-FIXES: std::print("Hello\r\n"); + + printf("Hello\r\\n"); + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] + // CHECK-FIXES: std::print("Hello\r\\n"); +} + // std::print returns nothing, so any callers that use the return // value cannot be automatically translated. int printf_uses_return_value(int choice) {