[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-28 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From 71dedefaf4dd8725b9a94e50c8f4d43b0e8bc4b2 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +-
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 65 +--
 .../clang-tidy/utils/FormatStringConverter.h  |  7 +-
 clang-tools-extra/docs/ReleaseNotes.rst   | 10 +++
 .../checks/modernize/use-std-print.rst| 22 +++---
 .../checkers/Inputs/Headers/inttypes.h| 26 +++---
 .../checkers/modernize/use-std-format.cpp | 79 ---
 .../checkers/modernize/use-std-print.cpp  | 73 -
 11 files changed, 255 insertions(+), 40 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..6deac7a0b88ec 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -76,9 +77,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..0ab92d0f05282 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -133,7 +134,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264..995c740389e73 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 
 private:
+  

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-28 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

@5chmidti wrote:
> Looks good from my side

Thanks. I've squashed and rebased. Since 19 has been branched now and it 
includes *modernize-use-std-format* I've mentioned the improvement as being for 
both *modernize-use-std-print* and *modernize-use-std-format* in the release 
notes whilst I was resolving the conflict.

https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-28 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From f7be65b1581e49bb18b3ab613686daedcd71b4d9 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +-
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 65 +--
 .../clang-tidy/utils/FormatStringConverter.h  |  7 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |  8 ++
 .../checks/modernize/use-std-print.rst| 22 +++---
 .../checkers/Inputs/Headers/inttypes.h| 26 +++---
 .../checkers/modernize/use-std-format.cpp | 79 ---
 .../checkers/modernize/use-std-print.cpp  | 73 -
 11 files changed, 253 insertions(+), 40 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..6deac7a0b88ec 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -76,9 +77,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..0ab92d0f05282 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -133,7 +134,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264..995c740389e73 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 
 private:
+  

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-27 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

@5chmidti wrote:
> It'll be 1 week+ before I am back at my main machine to take a better look at 
> the macro question. Maybe this can just be landed, without that distinction.

Thanks for letting me know and thanks for the review.

I've pushed a new version to this PR with the typo you spotted fixed and 
removing the commit containing the debug output for exploring the macro 
detection (the version with the extra debug is at 
https://github.com/mikecrowe/clang-tidy-fmt/commits/mac/fix-use-std-print-macro-expansion-investigation/
 if you still need it).

I'll let you and @PiotrZSL decide whether you want to land this PR as it is 
since I don't have permission to do so myself.

https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-27 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From f6c1a231681092189a621e2bc6af97300b2a7bfa Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH 1/6] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +--
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 52 --
 .../clang-tidy/utils/FormatStringConverter.h  |  6 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../checks/modernize/use-std-print.rst| 22 
 .../checkers/Inputs/Headers/inttypes.h| 26 +
 .../checkers/modernize/use-std-format.cpp | 53 +++
 .../checkers/modernize/use-std-print.cpp  | 47 +++-
 11 files changed, 181 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b37..7e8cbd40fe07a 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -78,9 +79,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd310..69136c10d927b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -137,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264..995c740389e73 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 
 

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-21 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

@5chmidti wrote:
> It should be possible to detect this case comparing the FileID of the call's 
> location and the format expression's location. If they differ, then they are 
> different arguments -> different macros. Although, I haven't checked that yet.

I had thought so too but I was unable to find any `SourceLocation` or `Lexer` 
functions that returned what I needed. I've pushed an extra commit to the 
branch for this PR that contains an extra LIT test and some debug output. The 
test contains:
```C++
SURROUND_ALL(printf(SURROUND_FORMAT_PARTIAL("%" FMT) "\n", "42"));
```
with the hope that I can detect that `SURROUND_ALL` is applied to both the 
`printf` and the `"\n"` but different macros are applied to the other tokens 
that make up the format string.

The debug output (with the filenames shortened for readability) is:
```
getImmediateExpansionRange for 'BeginCallLoc': 
>
getExpansionRange for 'BeginCallLoc': 
getTopMacroCaller for 'BeginCallLoc': use-std-print-macro.cpp.tmp.cpp:16:16
getImmediateMacroCallerLoc for 'BeginCallLoc': 
use-std-print-macro.cpp.tmp.cpp:16:16
getImmediateSpellingLoc for 'BeginCallLoc': 
use-std-print-macro.cpp.tmp.cpp:16:16
getFileLoc for 'BeginCallLoc': use-std-print-macro.cpp.tmp.cpp:16:16

getImmediateExpansionRange for 'SURROUND_FORMAT_PARTIAL': 
>
getExpansionRange for 'SURROUND_FORMAT_PARTIAL': 

getTopMacroCaller for 'SURROUND_FORMAT_PARTIAL': 
use-std-print-macro.cpp.tmp.cpp:16:47
getImmediateMacroCallerLoc for 'SURROUND_FORMAT_PARTIAL': 
use-std-print-macro.cpp.tmp.cpp:16:23 

getImmediateSpellingLoc for 'SURROUND_FORMAT_PARTIAL': 
use-std-print-macro.cpp.tmp.cpp:16:23 

getFileLoc for 'SURROUND_FORMAT_PARTIAL': use-std-print-macro.cpp.tmp.cpp:16:47

getImmediateExpansionRange for 'FMT': >
getExpansionRange for 'FMT': 
getTopMacroCaller for 'FMT': use-std-print-macro.cpp.tmp.cpp:16:51 

getImmediateMacroCallerLoc for 'FMT': use-std-print-macro.cpp.tmp.cpp:16:23 

getImmediateSpellingLoc for 'FMT': use-std-print-macro.cpp.tmp.cpp:16:23 

getFileLoc for 'FMT': use-std-print-macro.cpp.tmp.cpp:16:51

getImmediateExpansionRange for 'SURROUND_ALL': 
>
getExpansionRange for 'SURROUND_ALL': 
getTopMacroCaller for 'SURROUND_ALL': use-std-print-macro.cpp.tmp.cpp:16:56
getImmediateMacroCallerLoc for 'SURROUND_ALL': 
use-std-print-macro.cpp.tmp.cpp:16:56
getImmediateSpellingLoc for 'SURROUND_ALL': 
use-std-print-macro.cpp.tmp.cpp:16:56
getFileLoc for 'SURROUND_ALL': use-std-print-macro.cpp.tmp.cpp:16:56
```
Although the last token inside `SURROUND_ALL` has a few functions which return 
the same location as for `BeginCallLoc`, these functions also return that 
location for the tokens inside other macros too. :(

The change also captures the FileID for `BeginCallLoc` and compares it against 
each `TokenLoc` but never gets a match.

Or perhaps I've misinterpreted what you meant. If so, please can you provide 
more details?


https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-21 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From f6c1a231681092189a621e2bc6af97300b2a7bfa Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH 1/6] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +--
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 52 --
 .../clang-tidy/utils/FormatStringConverter.h  |  6 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../checks/modernize/use-std-print.rst| 22 
 .../checkers/Inputs/Headers/inttypes.h| 26 +
 .../checkers/modernize/use-std-format.cpp | 53 +++
 .../checkers/modernize/use-std-print.cpp  | 47 +++-
 11 files changed, 181 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b37..7e8cbd40fe07a 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -78,9 +79,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd310..69136c10d927b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -137,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264..995c740389e73 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 
 

[clang-tools-extra] [clang-tidy] Fix modernize-use-std-print/format for fmt (PR #99021)

2024-07-16 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

The previous fix hadn't made it into a release yet, so I don't think that this 
newly-discovered problem requires mentioning in the release notes. I'm happy to 
create a separate issue for it if you'd like me to though.

https://github.com/llvm/llvm-project/pull/99021
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix modernize-use-std-print/format for fmt (PR #99021)

2024-07-16 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe created 
https://github.com/llvm/llvm-project/pull/99021

When fixing #92896 in 0e62d5cf55479981da5e05e406bbca4afb3cdc4f (#94104) I 
failed to spot that I'd broken converting from fmt::printf, fmt::fprintf and 
fmt::sprintf in these checks since the format parameter of those functions is 
not a simple character pointer.

The first part of the previous fix to avoid the assert and instead produce an 
error message was sufficient. It was only the second part that required the 
format parameter of the called function to be a simple character pointer that 
was problematic. Let's remove that second part and add the now-expected error 
messages to the lit tests along with fixing the prototype for the fmt functions 
to more accurately reflect the ones used by the fmt library so they are 
actually useful.

Fixes #92896

>From af0225dd9679a4e2b6fe0070c9c55c12ea406e42 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Mon, 15 Jul 2024 21:32:50 +0100
Subject: [PATCH] [clang-tidy] Fix modernize-use-std-print/format for fmt

When fixing #92896 in 0e62d5cf55479981da5e05e406bbca4afb3cdc4f (#94104)
I failed to spot that I'd broken converting from fmt::printf,
fmt::fprintf and fmt::sprintf in these checks since the format parameter
of those functions is not a simple character pointer.

The first part of the previous fix to avoid the assert and instead
produce an error message was sufficient. It was only the second part
that required the format parameter of the called function to be a simple
character pointer that was problematic. Let's remove that second part
and add the now-expected error messages to the lit tests along with
fixing the prototype for the fmt functions to more accurately reflect
the ones used by the fmt library so they are actually useful.

Fixes #92896
---
 .../modernize/UseStdFormatCheck.cpp   | 14 +-
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 ---
 .../modernize/use-std-format-custom.cpp   |  1 +
 .../checkers/modernize/use-std-format-fmt.cpp |  6 ++---
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b37..6cef21f1318a2 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -47,15 +47,13 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
-  auto CharPointerType =
-  hasType(pointerType(pointee(matchers::isSimpleChar(;
   Finder->addMatcher(
-  callExpr(
-  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
-  callee(functionDecl(
- unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
- matchers::matchesAnyListedName(StrFormatLikeFunctions))
- .bind("func_decl")))
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd310..ff990feadc0c1 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -95,15 +95,12 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
-  auto CharPointerType =
-  hasType(pointerType(pointee(matchers::isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
- hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -116,7 +113,6 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
- hasParameter(1, CharPointerType),
  

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-14 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

> Unfortunately, walking the format string looking for macros also seems to 
> match a macro that encloses the whole function invocation. This results in 
> the check failing to work on expressions inside Catch2 `REQUIRE` macros for 
> example.
> 
> My new test case (that currently fails) is:
> 
> ```c++
> #define SURROUND(x) x
>   SURROUND(printf("Surrounding macro %d\n", 42));
>   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 
> 'printf' [modernize-use-std-print]
>   // CHECK-FIXES: std::print("Surrounding macro {}", 42);
> ```
> 
> I'll try to fix this, but any advice is gratefully received.

I've pushed a new commit that works for the Lit test cases that I've added by 
getting the macro name for the function call and permitting that macro for the 
format string too. I can't say that I'm particularly happy with it, and there 
may be corner cases such as the same macro being intentionally used in both 
places, but it's the best I can currently work out how to do.

https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-14 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From f6c1a231681092189a621e2bc6af97300b2a7bfa Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH 1/4] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +--
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 52 --
 .../clang-tidy/utils/FormatStringConverter.h  |  6 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../checks/modernize/use-std-print.rst| 22 
 .../checkers/Inputs/Headers/inttypes.h| 26 +
 .../checkers/modernize/use-std-format.cpp | 53 +++
 .../checkers/modernize/use-std-print.cpp  | 47 +++-
 11 files changed, 181 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b37..7e8cbd40fe07a 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -78,9 +79,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd310..69136c10d927b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -137,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264..995c740389e73 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 
 

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-11 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

Unfortunately, walking the format string looking for macros also seems to match 
a macro that encloses the whole function invocation. This results in the check 
failing to work on expressions inside Catch2 `REQUIRE` macros for example.

My new test case (that currently fails) is:
```c++
#define SURROUND(x) x
  SURROUND(printf("Surrounding macro %d\n", 42));
  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 
'printf' [modernize-use-std-print]
  // CHECK-FIXES: std::print("Surrounding macro {}", 42);
```
I'll try to fix this, but any advice is gratefully received.

https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-09 Thread Mike Crowe via cfe-commits


@@ -230,6 +241,37 @@ FormatStringConverter::FormatStringConverter(ASTContext 
*ContextIn,
   finalizeFormatText();
 }
 
+std::optional
+FormatStringConverter::formatStringContainsUnreplaceableMacro(
+const StringLiteral *FormatExpr, SourceManager , Preprocessor ) {
+  for (auto I = FormatExpr->tokloc_begin(), E = FormatExpr->tokloc_end();
+   I != E; ++I) {
+const SourceLocation  = *I;
+if (TokenLoc.isMacroID()) {
+  const StringRef MacroName =
+  Lexer::getImmediateMacroName(TokenLoc, SM, PP.getLangOpts());
+
+  // glibc uses __PRI64_PREFIX and __PRIPTR_PREFIX to define the prefixes
+  // for types that change size so we must look for multiple prefixes.
+  if (!MacroName.starts_with("PRI") && !MacroName.starts_with("__PRI"))
+return MacroName;
+
+  const SourceLocation TokenSpellingLoc = SM.getSpellingLoc(TokenLoc);

mikecrowe wrote:

Do you mean that I should check whether the `SourceLocation` returned from 
`SourceManager::getSpellingLoc()` is valid?

Looking at the `SourceLocation` documentation and other checks that call 
`SourceManager::getSpellingLoc()` I was unable to spot how to tell whether the 
location returned is valid. All the other callers I looked at just went on to 
use the returned location without any checking.

Can I arrange for an invalid location to be returned from the lit test somehow 
to test this case?

https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-07 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-07 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From f6c1a231681092189a621e2bc6af97300b2a7bfa Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH 1/3] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +--
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 52 --
 .../clang-tidy/utils/FormatStringConverter.h  |  6 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../checks/modernize/use-std-print.rst| 22 
 .../checkers/Inputs/Headers/inttypes.h| 26 +
 .../checkers/modernize/use-std-format.cpp | 53 +++
 .../checkers/modernize/use-std-print.cpp  | 47 +++-
 11 files changed, 181 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b37..7e8cbd40fe07a 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -78,9 +79,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd310..69136c10d927b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -137,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264..995c740389e73 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 
 

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-07 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

It looks like the tests are failing on Windows because the `%s` in the command 
line
```
// RUN: %check_clang_tidy \
// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
// RUN:   -config="{CheckOptions: {StrictMode: true}}" \
// RUN:   -- -isystem %clang_tidy_headers \
// RUN:  -DPRI_CMDLINE_MACRO="\"%s\"" \
// RUN:  -D__PRI_CMDLINE_MACRO="\"%s\""
```
is being replaced by the filename for the LIT test:
```
| Running ['clang-tidy', 
'C:\\ws\\src\\build\\tools\\clang\\tools\\extra\\test\\clang-tidy\\checkers\\modernize\\Output\\use-std-format.cpp.tmp.cpp',
 '-fix', '--checks=-*,modernize-use-std-format', '-config={CheckOptions: 
{StrictMode: true}}', '--', '-isystem', 
'C:/ws/src/clang-tools-extra/test/../test\\clang-tidy\\checkers\\Inputs\\Headers',
 
'-DPRI_CMDLINE_MACRO="C:\\ws\\src\\clang-tools-extra\\test\\clang-tidy\\checkers\\modernize\\use-std-format.cpp"',
 
'-D__PRI_CMDLINE_MACRO="C:\\ws\\src\\clang-tools-extra\\test\\clang-tidy\\checkers\\modernize\\use-std-format.cpp"',
 '-std=c++20', '-nostdinc++']...
```
I can believe that this is being done by `TestRunner.py` (or some other part of 
llvm-lit) since that's expected for the first `%s` on the command line, but the 
surprise is that it doesn't also do this on Linux. Nevertheless, I'll modify 
the tests to avoid using `%` at all in the macros on the command line.

https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-07 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/97911

>From f6c1a231681092189a621e2bc6af97300b2a7bfa Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH 1/2] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +--
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 52 --
 .../clang-tidy/utils/FormatStringConverter.h  |  6 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../checks/modernize/use-std-print.rst| 22 
 .../checkers/Inputs/Headers/inttypes.h| 26 +
 .../checkers/modernize/use-std-format.cpp | 53 +++
 .../checkers/modernize/use-std-print.cpp  | 47 +++-
 11 files changed, 181 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b375..7e8cbd40fe07ae 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -78,9 +79,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4bc..9ac2240212ebf6 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd3106..69136c10d927b2 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -137,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? ReplacementPrintlnFunction
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
index 7a06cf38b4264f..995c740389e73b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h
@@ -36,6 +36,7 @@ class UseStdPrintCheck : public ClangTidyCheck {
   }
 

[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-06 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

I'm not particularly happy with the `FormatStringConverter` constructor now 
taking seven parameters. The risk of them getting muddled isn't huge though 
because they are all of different types. Should I perhaps put them all into the 
`FormatStringConverter::Configuration` struct or perhaps a separate struct in 
the absence of named parameters? Even if I leave them as seven parameters, is 
there a preferred order for them? Any recommendations gratefully received.

I considered adding a configuration option to list other macros that should be 
permitted in the format string. I will investigate doing so if this change is 
acceptable.

OpenBSD and mingw32 seem to just use `PRI` prefixes in their `inttypes.h`. I 
don't know whether Microsoft and MacOS do anything like glibc does which 
required the special `__PRI` handling.


https://github.com/llvm/llvm-project/pull/97911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Only expand macros in modernize-use-std-format/print (PR #97911)

2024-07-06 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe created 
https://github.com/llvm/llvm-project/pull/97911

Expanding all macros in the printf/absl::StrFormat format string before 
conversion could easily break code if those macros are expended to change their 
definition between builds. It's important for this check to expand the 
 PRI macros though, so let's ensure that the presence of any other 
macros in the format string causes the check to emit a warning and not perform 
any conversion.

>From f6c1a231681092189a621e2bc6af97300b2a7bfa Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Wed, 12 Jun 2024 21:06:26 +0100
Subject: [PATCH] [clang-tidy] Only expand  macros in
 modernize-use-std-format/print

Expanding all macros in the printf/absl::StrFormat format string before
conversion could easily break code if those macros are expended to
change their definition between builds. It's important for this check to
expand the  PRI macros though, so let's ensure that the
presence of any other macros in the format string causes the check to
emit a warning and not perform any conversion.
---
 .../modernize/UseStdFormatCheck.cpp   |  7 +--
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  1 +
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  4 +-
 .../clang-tidy/modernize/UseStdPrintCheck.h   |  1 +
 .../utils/FormatStringConverter.cpp   | 52 --
 .../clang-tidy/utils/FormatStringConverter.h  |  6 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../checks/modernize/use-std-print.rst| 22 
 .../checkers/Inputs/Headers/inttypes.h| 26 +
 .../checkers/modernize/use-std-format.cpp | 53 +++
 .../checkers/modernize/use-std-print.cpp  | 47 +++-
 11 files changed, 181 insertions(+), 41 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index d082faa786b37..7e8cbd40fe07a 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -44,6 +44,7 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
@@ -78,9 +79,9 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult 
) {
 
   utils::FormatStringConverter::Configuration ConverterConfig;
   ConverterConfig.StrictMode = StrictMode;
-  utils::FormatStringConverter Converter(Result.Context, StrFormat,
- FormatArgOffset, ConverterConfig,
- getLangOpts());
+  utils::FormatStringConverter Converter(
+  Result.Context, StrFormat, FormatArgOffset, ConverterConfig,
+  getLangOpts(), *Result.SourceManager, *PP);
   const Expr *StrFormatCall = StrFormat->getCallee();
   if (!Converter.canApply()) {
 diag(StrFormat->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
index b59a4708c6e4b..9ac2240212ebf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
@@ -44,6 +44,7 @@ class UseStdFormatCheck : public ClangTidyCheck {
   StringRef ReplacementFormatFunction;
   utils::IncludeInserter IncludeInserter;
   std::optional MaybeHeaderToInclude;
+  Preprocessor *PP = nullptr;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 1ea170c3cd310..69136c10d927b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -68,6 +68,7 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager ,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
+  this->PP = PP;
 }
 
 static clang::ast_matchers::StatementMatcher
@@ -137,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   ConverterConfig.StrictMode = StrictMode;
   ConverterConfig.AllowTrailingNewlineRemoval = true;
   utils::FormatStringConverter Converter(
-  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts());
+  Result.Context, Printf, FormatArgOffset, ConverterConfig, getLangOpts(),
+  *Result.SourceManager, *PP);
   const Expr *PrintfCall = Printf->getCallee();
   const StringRef ReplacementFunction = Converter.usePrintNewlineFunction()
 ? 

[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

Thank you @PiotrZSL!

https://github.com/llvm/llvm-project/pull/94104
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

> LGTM

Thanks for the review. Please can you squash and land it for me? I don't have 
permission to do so.

https://github.com/llvm/llvm-project/pull/94104
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits


@@ -351,6 +351,10 @@ Changes in existing checks
   ` check to also handle
   calls to ``compare`` method.
 
+- Improved :doc:`modernize-use-std-format` and

mikecrowe wrote:

I spotted that just too late...

https://github.com/llvm/llvm-project/pull/94104
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/94104

>From 2972062997ca582100b5797cd548c4dc2f80c69a Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Fri, 31 May 2024 21:27:03 +0100
Subject: [PATCH 1/3] [clang-tidy] Fix assert in modernize-use-std-format/print

Ensure that FormatStringConverter's constructor fails with a sensible
error message rather than asserting if the format string is not a narrow
string literal.

Also, ensure that we don't even get that far in modernize-use-std-print
and modernize-use-std-format by checking that the format string
parameter is a char pointer.

Fixes #92896
---
 .../modernize/UseStdFormatCheck.cpp   | 18 -
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  8 ++
 .../utils/FormatStringConverter.cpp   |  8 +++---
 .../modernize/use-std-format-custom.cpp   | 18 +++--
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..5c72f8f22dec7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
@@ -47,13 +52,14 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   Finder->addMatcher(
-  callExpr(argumentCountAtLeast(1),
-   hasArgument(0, stringLiteral(isOrdinary())),
-   callee(functionDecl(unless(cxxMethodDecl()),
-   matchers::matchesAnyListedName(
-   StrFormatLikeFunctions))
-  .bind("func_decl")))
+  callExpr(
+  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
+  callee(functionDecl(
+ unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
+ matchers::matchesAnyListedName(StrFormatLikeFunctions))
+ .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..6a4497eaf7f60 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context)
@@ -95,12 +100,14 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -113,6 +120,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(1, CharPointerType),
  matchers::matchesAnyListedName(
  FprintfLikeFunctions))
 .bind("func_decl")))
diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp 
b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
index 

[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/94104

>From 2972062997ca582100b5797cd548c4dc2f80c69a Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Fri, 31 May 2024 21:27:03 +0100
Subject: [PATCH 1/3] [clang-tidy] Fix assert in modernize-use-std-format/print

Ensure that FormatStringConverter's constructor fails with a sensible
error message rather than asserting if the format string is not a narrow
string literal.

Also, ensure that we don't even get that far in modernize-use-std-print
and modernize-use-std-format by checking that the format string
parameter is a char pointer.

Fixes #92896
---
 .../modernize/UseStdFormatCheck.cpp   | 18 -
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  8 ++
 .../utils/FormatStringConverter.cpp   |  8 +++---
 .../modernize/use-std-format-custom.cpp   | 18 +++--
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..5c72f8f22dec7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
@@ -47,13 +52,14 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   Finder->addMatcher(
-  callExpr(argumentCountAtLeast(1),
-   hasArgument(0, stringLiteral(isOrdinary())),
-   callee(functionDecl(unless(cxxMethodDecl()),
-   matchers::matchesAnyListedName(
-   StrFormatLikeFunctions))
-  .bind("func_decl")))
+  callExpr(
+  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
+  callee(functionDecl(
+ unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
+ matchers::matchesAnyListedName(StrFormatLikeFunctions))
+ .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..6a4497eaf7f60 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context)
@@ -95,12 +100,14 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -113,6 +120,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(1, CharPointerType),
  matchers::matchesAnyListedName(
  FprintfLikeFunctions))
 .bind("func_decl")))
diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp 
b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
index 

[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/94104

>From 2972062997ca582100b5797cd548c4dc2f80c69a Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Fri, 31 May 2024 21:27:03 +0100
Subject: [PATCH 1/3] [clang-tidy] Fix assert in modernize-use-std-format/print

Ensure that FormatStringConverter's constructor fails with a sensible
error message rather than asserting if the format string is not a narrow
string literal.

Also, ensure that we don't even get that far in modernize-use-std-print
and modernize-use-std-format by checking that the format string
parameter is a char pointer.

Fixes #92896
---
 .../modernize/UseStdFormatCheck.cpp   | 18 -
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  8 ++
 .../utils/FormatStringConverter.cpp   |  8 +++---
 .../modernize/use-std-format-custom.cpp   | 18 +++--
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..5c72f8f22dec7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
@@ -47,13 +52,14 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   Finder->addMatcher(
-  callExpr(argumentCountAtLeast(1),
-   hasArgument(0, stringLiteral(isOrdinary())),
-   callee(functionDecl(unless(cxxMethodDecl()),
-   matchers::matchesAnyListedName(
-   StrFormatLikeFunctions))
-  .bind("func_decl")))
+  callExpr(
+  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
+  callee(functionDecl(
+ unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
+ matchers::matchesAnyListedName(StrFormatLikeFunctions))
+ .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..6a4497eaf7f60 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context)
@@ -95,12 +100,14 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -113,6 +120,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(1, CharPointerType),
  matchers::matchesAnyListedName(
  FprintfLikeFunctions))
 .bind("func_decl")))
diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp 
b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
index 

[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-03 Thread Mike Crowe via cfe-commits


@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}

mikecrowe wrote:

OK. I probably ought to do the same with `isOrdinary` too, but I'll do that in 
a separate change.

https://github.com/llvm/llvm-project/pull/94104
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-01 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/94104
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (PR #94104)

2024-06-01 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/94104
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (#92896) (PR #94104)

2024-06-01 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/94104

>From 2972062997ca582100b5797cd548c4dc2f80c69a Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Fri, 31 May 2024 21:27:03 +0100
Subject: [PATCH] [clang-tidy] Fix assert in modernize-use-std-format/print

Ensure that FormatStringConverter's constructor fails with a sensible
error message rather than asserting if the format string is not a narrow
string literal.

Also, ensure that we don't even get that far in modernize-use-std-print
and modernize-use-std-format by checking that the format string
parameter is a char pointer.

Fixes #92896
---
 .../modernize/UseStdFormatCheck.cpp   | 18 -
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  8 ++
 .../utils/FormatStringConverter.cpp   |  8 +++---
 .../modernize/use-std-format-custom.cpp   | 18 +++--
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..5c72f8f22dec7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
@@ -47,13 +52,14 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   Finder->addMatcher(
-  callExpr(argumentCountAtLeast(1),
-   hasArgument(0, stringLiteral(isOrdinary())),
-   callee(functionDecl(unless(cxxMethodDecl()),
-   matchers::matchesAnyListedName(
-   StrFormatLikeFunctions))
-  .bind("func_decl")))
+  callExpr(
+  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
+  callee(functionDecl(
+ unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
+ matchers::matchesAnyListedName(StrFormatLikeFunctions))
+ .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..6a4497eaf7f60 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context)
@@ -95,12 +100,14 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -113,6 +120,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(1, CharPointerType),
  matchers::matchesAnyListedName(
  FprintfLikeFunctions))
 .bind("func_decl")))
diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp 
b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
index 

[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (#92896) (PR #94104)

2024-06-01 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/94104

>From 54135a6f8fd9491e6b94e4d96e46f2909e344307 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Fri, 31 May 2024 21:27:03 +0100
Subject: [PATCH] [clang-tidy] Fix assert in modernize-use-std-format/print
 (#92896)

Ensure that FormatStringConverter's constructor fails with a sensible
error message rather than asserting if the format string is not a narrow
string literal.

Also, ensure that we don't even get that far in modernize-use-std-print
and modernize-use-std-format by checking that the format string
parameter is a char pointer.

Fixes #92896
---
 .../modernize/UseStdFormatCheck.cpp   | 18 -
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  8 ++
 .../utils/FormatStringConverter.cpp   |  8 +++---
 .../modernize/use-std-format-custom.cpp   | 18 +++--
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..5c72f8f22dec7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
@@ -47,13 +52,14 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   Finder->addMatcher(
-  callExpr(argumentCountAtLeast(1),
-   hasArgument(0, stringLiteral(isOrdinary())),
-   callee(functionDecl(unless(cxxMethodDecl()),
-   matchers::matchesAnyListedName(
-   StrFormatLikeFunctions))
-  .bind("func_decl")))
+  callExpr(
+  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
+  callee(functionDecl(
+ unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
+ matchers::matchesAnyListedName(StrFormatLikeFunctions))
+ .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..6a4497eaf7f60 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context)
@@ -95,12 +100,14 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -113,6 +120,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(1, CharPointerType),
  matchers::matchesAnyListedName(
  FprintfLikeFunctions))
 .bind("func_decl")))
diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp 
b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp

[clang-tools-extra] [clang-tidy] Fix assert in modernize-use-std-format/print (#92896) (PR #94104)

2024-06-01 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe created 
https://github.com/llvm/llvm-project/pull/94104

Ensure that FormatStringConverter's constructor fails with a sensible error 
message rather than asserting if the format string is not a narrow string 
literal.

Also, ensure that we don't even get that far in modernize-use-std-print and 
modernize-use-std-format by checking that the format string parameter is a char 
pointer.

>From 845879284bf80f5abb99eb2a86f90255fc57827b Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Fri, 31 May 2024 21:27:03 +0100
Subject: [PATCH] [clang-tidy] Avoid assertion failure in
 modernize-use-std-format/print (#92896)

Ensure that FormatStringConverter's constructor fails with a sensible
error message rather than asserting if the format string is not a narrow
string literal.

Also, ensure that we don't even get that far in modernize-use-std-print
and modernize-use-std-format by checking that the format string
parameter is a char pointer.
---
 .../modernize/UseStdFormatCheck.cpp   | 18 -
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  8 ++
 .../utils/FormatStringConverter.cpp   |  8 +++---
 .../modernize/use-std-format-custom.cpp   | 18 +++--
 .../modernize/use-std-print-custom.cpp| 26 +--
 5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
index 6cef21f1318a2..5c72f8f22dec7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
@@ -47,13 +52,14 @@ void UseStdFormatCheck::registerPPCallbacks(const 
SourceManager ,
 }
 
 void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   Finder->addMatcher(
-  callExpr(argumentCountAtLeast(1),
-   hasArgument(0, stringLiteral(isOrdinary())),
-   callee(functionDecl(unless(cxxMethodDecl()),
-   matchers::matchesAnyListedName(
-   StrFormatLikeFunctions))
-  .bind("func_decl")))
+  callExpr(
+  argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())),
+  callee(functionDecl(
+ unless(cxxMethodDecl()), hasParameter(0, CharPointerType),
+ matchers::matchesAnyListedName(StrFormatLikeFunctions))
+ .bind("func_decl")))
   .bind("strformat"),
   this);
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index ff990feadc0c1..6a4497eaf7f60 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -20,6 +20,11 @@ namespace clang::tidy::modernize {
 
 namespace {
 AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+AST_MATCHER(QualType, isSimpleChar) {
+  const auto ActualType = Node.getTypePtr();
+  return ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
+ ActualType->isSpecificBuiltinType(BuiltinType::Char_U);
+}
 } // namespace
 
 UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context)
@@ -95,12 +100,14 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher 
MatchedCallExpr) {
 }
 
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
+  auto CharPointerType = hasType(pointerType(pointee(isSimpleChar(;
   if (!PrintfLikeFunctions.empty())
 Finder->addMatcher(
 unusedReturnValue(
 callExpr(argumentCountAtLeast(1),
  hasArgument(0, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(0, CharPointerType),
  matchers::matchesAnyListedName(
  PrintfLikeFunctions))
 .bind("func_decl")))
@@ -113,6 +120,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder 
*Finder) {
 callExpr(argumentCountAtLeast(2),
  hasArgument(1, stringLiteral(isOrdinary())),
  callee(functionDecl(unless(cxxMethodDecl()),
+ hasParameter(1, CharPointerType),

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-11 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

@PiotrZSL wrote:
> Once build will pass, I will land this change, and fixes could be done in 
> separate PR for both checks.

The build seems to be passing. Please can you land this if you are happy?

Thanks.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)

2024-05-05 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

@5chmidti wrote:
> LGTM, thanks

Please can you land this for me since I don't have permission to do so myself? 
(Assuming you do have permission.)

Thanks.

https://github.com/llvm/llvm-project/pull/91069
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)

2024-05-05 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/91069

>From 442cc7464ea4972d25e6fe518ac466b540a399eb Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sat, 4 May 2024 17:21:02 +0100
Subject: [PATCH] [clang-tidy][docs] Fix modernize-use-std-print docs

The set of functions for the PrintfLikeFunctions and
FprintfLikeFunctions options replaces the default, so remove the word
"extra" from the description which implies that they are in addition to
the default.
---
 .../docs/clang-tidy/checks/modernize/use-std-print.rst| 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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
index 9bb691e9d9512e..79648a1104bca2 100644
--- 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
@@ -118,7 +118,7 @@ Options
 
 .. option:: PrintfLikeFunctions
 
-   A semicolon-separated list of (fully qualified) extra function names to
+   A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter contains the
printf-style format string and the arguments to be formatted follow
immediately afterwards. If neither this option nor
@@ -128,7 +128,7 @@ Options
 
 .. option:: FprintfLikeFunctions
 
-   A semicolon-separated list of (fully qualified) extra function names to
+   A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter is retained, the
second parameter contains the printf-style format string and the
arguments to be formatted follow immediately afterwards. If neither this

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)

2024-05-05 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

@5chmidti wrote:
> LGTM, thanks

Please can you land this for me since I don't have permission to do so myself? 
(Assuming you do have permission.)

Thanks.

https://github.com/llvm/llvm-project/pull/91071
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)

2024-05-05 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/91071

>From d25fa679a70947d42fe3125858741508475d67c0 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sat, 4 May 2024 17:41:37 +0100
Subject: [PATCH] [clang-tidy] Improve modernize-use-std-print diagnostic

Include the source range of the printf function in the diagnostic so
it gets underlined in the output.
---
 clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 660996aba7b70d..aa60c904a363da 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -138,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   if (!Converter.canApply()) {
 diag(PrintfCall->getBeginLoc(),
  "unable to use '%0' instead of %1 because %2")
-<< ReplacementFunction << OldFunction->getIdentifier()
+<< PrintfCall->getSourceRange() << ReplacementFunction
+<< OldFunction->getIdentifier()
 << Converter.conversionNotPossibleReason();
 return;
   }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)

2024-05-04 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

As suggested by @5chmidti in 
https://github.com/llvm/llvm-project/pull/90397/files/54c325d7a5e24441adbe8036800a2f50e2ff5fa0#r1589445886
 .

https://github.com/llvm/llvm-project/pull/91071
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,107 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  StrFormatLikeFunctions(utils::options::parseStringList(
+  Options.get("StrFormatLikeFunctions", ""))),
+  ReplacementFormatFunction(
+  Options.get("ReplacementFormatFunction", "std::format")),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()),
+  MaybeHeaderToInclude(Options.get("FormatHeader")) {
+  if (StrFormatLikeFunctions.empty())
+StrFormatLikeFunctions.push_back("absl::StrFormat");
+
+  if (!MaybeHeaderToInclude && ReplacementFormatFunction == "std::format")
+MaybeHeaderToInclude = "";
+}
+
+void UseStdFormatCheck::registerPPCallbacks(const SourceManager ,
+Preprocessor *PP,
+Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
+  .bind("strformat"),
+  this);
+}
+
+void UseStdFormatCheck::storeOptions(ClangTidyOptions::OptionMap ) {
+  using utils::options::serializeStringList;
+  Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "StrFormatLikeFunctions",
+serializeStringList(StrFormatLikeFunctions));
+  Options.store(Opts, "ReplacementFormatFunction", ReplacementFormatFunction);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  if (MaybeHeaderToInclude)
+Options.store(Opts, "FormatHeader", *MaybeHeaderToInclude);
+}
+
+void UseStdFormatCheck::check(const MatchFinder::MatchResult ) {
+  const unsigned FormatArgOffset = 0;
+  const auto *OldFunction = Result.Nodes.getNodeAs("func_decl");
+  const auto *StrFormat = Result.Nodes.getNodeAs("strformat");
+
+  utils::FormatStringConverter::Configuration ConverterConfig;
+  ConverterConfig.StrictMode = StrictMode;
+  utils::FormatStringConverter Converter(Result.Context, StrFormat,
+ FormatArgOffset, ConverterConfig,
+ getLangOpts());
+  const Expr *StrFormatCall = StrFormat->getCallee();
+  if (!Converter.canApply()) {
+DiagnosticBuilder Diag = diag(StrFormat->getBeginLoc(),
+  "unable to use '%0' instead of %1 because 
%2")
+ << ReplacementFormatFunction
+ << OldFunction->getIdentifier()
+ << Converter.conversionNotPossibleReason();

mikecrowe wrote:

The use-std-print equivalent is in 
https://github.com/llvm/llvm-project/pull/91071 .

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Improve modernize-use-std-print diagnostic (PR #91071)

2024-05-04 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe created 
https://github.com/llvm/llvm-project/pull/91071

Include the source range of the printf function in the diagnostic so it gets 
underlined in the output.

>From d0ccc6ade357155161977446b64c50cafa100edb Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sat, 4 May 2024 17:41:37 +0100
Subject: [PATCH] [clang-tidy] Improve modernize-use-std-print diagnostic

Include the source range of the printf function in the diagnostic so
it gets underlined in the output.
---
 clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index 660996aba7b70d..aa60c904a363da 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -138,7 +138,8 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult 
) {
   if (!Converter.canApply()) {
 diag(PrintfCall->getBeginLoc(),
  "unable to use '%0' instead of %1 because %2")
-<< ReplacementFunction << OldFunction->getIdentifier()
+<< PrintfCall->getSourceRange() << ReplacementFunction
+<< OldFunction->getIdentifier()
 << Converter.conversionNotPossibleReason();
 return;
   }

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)

2024-05-04 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

The equivalent mistake was spotted by @5chmidti in 
https://github.com/llvm/llvm-project/pull/90397/files/54c325d7a5e24441adbe8036800a2f50e2ff5fa0#r1589697782
 in the new use-std-format check.

https://github.com/llvm/llvm-project/pull/91069
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,84 @@
+.. title:: clang-tidy - modernize-use-std-format
+
+modernize-use-std-format
+
+
+Converts calls to ``absl::StrFormat``, or other functions via
+configuration options, to C++20's ``std::format``, or another function
+via a configuration option, modifying the format string appropriately and
+removing now-unnecessary calls to ``std::string::c_str()`` and
+``std::string::data()``.
+
+For example, it turns lines like
+
+.. code-block:: c++
+
+  return absl::StrFormat("The %s is %3d", description.c_str(), value);
+
+into:
+
+.. code-block:: c++
+
+  return std::format("The {} is {:3}", description, value);
+
+The check uses the same format-string-conversion algorithm as
+`modernize-use-std-print <../modernize/use-std-print.html>`_ and its
+shortcomings are described in the documentation for that check.
+
+Options
+---
+
+.. option:: StrictMode
+
+   When `true`, the check will add casts when converting from variadic
+   functions and printing signed or unsigned integer types (including
+   fixed-width integer types from , ``ptrdiff_t``, ``size_t``
+   and ``ssize_t``) as the opposite signedness to ensure that the output
+   would matches that of a simple wrapper for ``std::sprintf`` that
+   accepted a C-style variable argument list. For example, with
+   `StrictMode` enabled,
+
+  .. code-block:: c++
+
+extern std::string strprintf(const char *format, ...);
+int i = -42;
+unsigned int u = 0x;
+return strprintf("%d %u\n", i, u);
+
+  would be converted to
+
+  .. code-block:: c++
+
+return std::format("{} {}\n", static_cast(i), 
static_cast(u));
+
+  to ensure that the output will continue to be the unsigned representation
+  of -42 and the signed representation of 0x (often 4294967254
+  and -1 respectively). When `false` (which is the default), these casts
+  will not be added which may cause a change in the output. Note that this
+  option makes no difference for the default value of
+  `StrFormatLikeFunctions` since ``absl::StrFormat`` takes a function
+  parameter pack and is not a variadic function.
+
+.. option:: StrFormatLikeFunctions
+
+   A semicolon-separated list of (fully qualified) extra function names to

mikecrowe wrote:

The fix for use-std-print is in https://github.com/llvm/llvm-project/pull/91069 
.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][docs] Fix modernize-use-std-print docs (PR #91069)

2024-05-04 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe created 
https://github.com/llvm/llvm-project/pull/91069

The set of functions for the PrintfLikeFunctions and FprintfLikeFunctions 
options replaces the default, so remove the word "extra" from the description 
which implies that they are in addition to the default.

>From e892c7d27ec71442dd8c6ca30ae195be374cbc64 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sat, 4 May 2024 17:21:02 +0100
Subject: [PATCH] [clang-tidy][docs] Fix modernize-use-std-print docs

The set of functions for the PrintfLikeFunctions and
FprintfLikeFunctions options replaces the default, so remove the word
"extra" from the description which implies that they are in addition to
the default.
---
 .../docs/clang-tidy/checks/modernize/use-std-print.rst| 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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
index 9bb691e9d9512e..79648a1104bca2 100644
--- 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
@@ -118,7 +118,7 @@ Options
 
 .. option:: PrintfLikeFunctions
 
-   A semicolon-separated list of (fully qualified) extra function names to
+   A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter contains the
printf-style format string and the arguments to be formatted follow
immediately afterwards. If neither this option nor
@@ -128,7 +128,7 @@ Options
 
 .. option:: FprintfLikeFunctions
 
-   A semicolon-separated list of (fully qualified) extra function names to
+   A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter is retained, the
second parameter contains the printf-style format string and the
arguments to be formatted follow immediately afterwards. If neither this

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 01/16] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits




mikecrowe wrote:

Thanks! I wasn't aware that was possible since I started with all these checks 
before fbf611ed2a768999202e2c5e1e1a6c3c6bb94725 and had been battling with the 
JSON syntax.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,84 @@
+.. title:: clang-tidy - modernize-use-std-format
+
+modernize-use-std-format
+
+
+Converts calls to ``absl::StrFormat``, or other functions via
+configuration options, to C++20's ``std::format``, or another function
+via a configuration option, modifying the format string appropriately and
+removing now-unnecessary calls to ``std::string::c_str()`` and
+``std::string::data()``.
+
+For example, it turns lines like
+
+.. code-block:: c++
+
+  return absl::StrFormat("The %s is %3d", description.c_str(), value);
+
+into:
+
+.. code-block:: c++
+
+  return std::format("The {} is {:3}", description, value);
+
+The check uses the same format-string-conversion algorithm as
+`modernize-use-std-print <../modernize/use-std-print.html>`_ and its
+shortcomings are described in the documentation for that check.
+
+Options
+---
+
+.. option:: StrictMode
+
+   When `true`, the check will add casts when converting from variadic
+   functions and printing signed or unsigned integer types (including
+   fixed-width integer types from , ``ptrdiff_t``, ``size_t``
+   and ``ssize_t``) as the opposite signedness to ensure that the output
+   would matches that of a simple wrapper for ``std::sprintf`` that
+   accepted a C-style variable argument list. For example, with
+   `StrictMode` enabled,
+
+  .. code-block:: c++
+
+extern std::string strprintf(const char *format, ...);
+int i = -42;
+unsigned int u = 0x;
+return strprintf("%d %u\n", i, u);
+
+  would be converted to
+
+  .. code-block:: c++
+
+return std::format("{} {}\n", static_cast(i), 
static_cast(u));
+
+  to ensure that the output will continue to be the unsigned representation
+  of -42 and the signed representation of 0x (often 4294967254
+  and -1 respectively). When `false` (which is the default), these casts
+  will not be added which may cause a change in the output. Note that this
+  option makes no difference for the default value of
+  `StrFormatLikeFunctions` since ``absl::StrFormat`` takes a function
+  parameter pack and is not a variadic function.
+
+.. option:: StrFormatLikeFunctions
+
+   A semicolon-separated list of (fully qualified) extra function names to

mikecrowe wrote:

True. I'll fix that.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,107 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  StrFormatLikeFunctions(utils::options::parseStringList(
+  Options.get("StrFormatLikeFunctions", ""))),
+  ReplacementFormatFunction(
+  Options.get("ReplacementFormatFunction", "std::format")),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()),
+  MaybeHeaderToInclude(Options.get("FormatHeader")) {
+  if (StrFormatLikeFunctions.empty())
+StrFormatLikeFunctions.push_back("absl::StrFormat");
+
+  if (!MaybeHeaderToInclude && ReplacementFormatFunction == "std::format")
+MaybeHeaderToInclude = "";
+}
+
+void UseStdFormatCheck::registerPPCallbacks(const SourceManager ,
+Preprocessor *PP,
+Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
+  .bind("strformat"),
+  this);
+}
+
+void UseStdFormatCheck::storeOptions(ClangTidyOptions::OptionMap ) {
+  using utils::options::serializeStringList;
+  Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "StrFormatLikeFunctions",
+serializeStringList(StrFormatLikeFunctions));
+  Options.store(Opts, "ReplacementFormatFunction", ReplacementFormatFunction);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  if (MaybeHeaderToInclude)
+Options.store(Opts, "FormatHeader", *MaybeHeaderToInclude);
+}
+
+void UseStdFormatCheck::check(const MatchFinder::MatchResult ) {
+  const unsigned FormatArgOffset = 0;
+  const auto *OldFunction = Result.Nodes.getNodeAs("func_decl");
+  const auto *StrFormat = Result.Nodes.getNodeAs("strformat");
+
+  utils::FormatStringConverter::Configuration ConverterConfig;
+  ConverterConfig.StrictMode = StrictMode;
+  utils::FormatStringConverter Converter(Result.Context, StrFormat,
+ FormatArgOffset, ConverterConfig,
+ getLangOpts());
+  const Expr *StrFormatCall = StrFormat->getCallee();
+  if (!Converter.canApply()) {
+DiagnosticBuilder Diag = diag(StrFormat->getBeginLoc(),
+  "unable to use '%0' instead of %1 because 
%2")
+ << ReplacementFormatFunction
+ << OldFunction->getIdentifier()
+ << Converter.conversionNotPossibleReason();

mikecrowe wrote:

OK. It looks like use-std-print needs that fix too, so I'll do that in a 
separate change. Is there a way to get the lit test to check for this?

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-04 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,107 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  StrFormatLikeFunctions(utils::options::parseStringList(
+  Options.get("StrFormatLikeFunctions", ""))),
+  ReplacementFormatFunction(
+  Options.get("ReplacementFormatFunction", "std::format")),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()),
+  MaybeHeaderToInclude(Options.get("FormatHeader")) {
+  if (StrFormatLikeFunctions.empty())
+StrFormatLikeFunctions.push_back("absl::StrFormat");
+
+  if (!MaybeHeaderToInclude && ReplacementFormatFunction == "std::format")
+MaybeHeaderToInclude = "";
+}
+
+void UseStdFormatCheck::registerPPCallbacks(const SourceManager ,
+Preprocessor *PP,
+Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
+  .bind("strformat"),
+  this);
+}
+
+void UseStdFormatCheck::storeOptions(ClangTidyOptions::OptionMap ) {
+  using utils::options::serializeStringList;
+  Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "StrFormatLikeFunctions",
+serializeStringList(StrFormatLikeFunctions));
+  Options.store(Opts, "ReplacementFormatFunction", ReplacementFormatFunction);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  if (MaybeHeaderToInclude)
+Options.store(Opts, "FormatHeader", *MaybeHeaderToInclude);
+}
+
+void UseStdFormatCheck::check(const MatchFinder::MatchResult ) {
+  const unsigned FormatArgOffset = 0;
+  const auto *OldFunction = Result.Nodes.getNodeAs("func_decl");
+  const auto *StrFormat = Result.Nodes.getNodeAs("strformat");
+
+  utils::FormatStringConverter::Configuration ConverterConfig;
+  ConverterConfig.StrictMode = StrictMode;
+  utils::FormatStringConverter Converter(Result.Context, StrFormat,
+ FormatArgOffset, ConverterConfig,
+ getLangOpts());
+  const Expr *StrFormatCall = StrFormat->getCallee();
+  if (!Converter.canApply()) {
+DiagnosticBuilder Diag = diag(StrFormat->getBeginLoc(),

mikecrowe wrote:

True. I'll fix that.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 01/12] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,120 @@
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: true}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: false}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+#include 
+// CHECK-FIXES: #include 
+
+namespace absl
+{
+// Use const char * for the format since the real type is hard to mock up.
+template 
+std::string StrFormat(const char *format, const Args&... args);
+} // namespace absl
+
+template 
+struct iterator {
+  T *operator->();
+  T *();
+};
+
+std::string StrFormat_simple() {
+  return absl::StrFormat("Hello");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Hello");
+}
+
+std::string StrFormat_complex(const char *name, double value) {
+  return absl::StrFormat("'%s'='%f'", name, value);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("'{}'='{:f}'", name, value);
+}
+
+std::string StrFormat_integer_conversions() {
+  return absl::StrFormat("int:%d int:%d char:%c char:%c", 65, 'A', 66, 'B');
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("int:{} int:{:d} char:{:c} char:{}", 65, 
'A', 66, 'B');
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_no_newline_removal() {
+  return absl::StrFormat("a line\n");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("a line\n");
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_cstr_removal(const std::string , const std::string 
*s2) {
+  return absl::StrFormat("%s %s %s %s", s1.c_str(), s1.data(), s2->c_str(), 
s2->data());
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("{} {} {} {}", s1, s1, *s2, *s2);
+}
+
+std::string StrFormat_strict_conversion() {
+  const unsigned char uc = 'A';
+  return absl::StrFormat("Integer %hhd from unsigned char\n", uc);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Integer {} from unsigned char\n", uc);
+}
+
+std::string StrFormat_field_width_and_precision() {
+  auto s1 = absl::StrFormat("width only:%*d width and precision:%*.*f 
precision only:%.*f", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width only:{:{}} width and precision:{:{}.{}f} 
precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
+
+  auto s2 = absl::StrFormat("width and precision positional:%1$*2$.*3$f 
after", 3.14159265358979323846, 4, 2);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width and precision positional:{0:{1}.{2}f} 
after", 3.14159265358979323846, 4, 2);
+
+  const int width = 10, precision = 3;
+  const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
+  auto s3 = absl::StrFormat("casts width only:%*d width and precision:%*.*d 
precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES-NOTSTRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
+  // CHECK-FIXES-STRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", static_cast(ui1), 3, 
static_cast(ui2), 4, 2, static_cast(ui3), 5);
+
+  auto s4 = absl::StrFormat("c_str removal width only:%*s width and 
precision:%*.*s precision only:%.*s", 3, s1.c_str(), 4, 2, s2.c_str(), 5, 
s3.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("c_str removal width only:{:>{}} width and 
precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
+
+  const std::string *ps1 = , *ps2 = , *ps3 = 
+  auto s5 = absl::StrFormat("c_str() removal pointer width only:%-*s width and 
precision:%-*.*s precision only:%-.*s", 3, ps1->c_str(), 4, 2, 

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,120 @@
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: true}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: false}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+#include 
+// CHECK-FIXES: #include 
+
+namespace absl
+{
+// Use const char * for the format since the real type is hard to mock up.
+template 
+std::string StrFormat(const char *format, const Args&... args);
+} // namespace absl
+
+template 
+struct iterator {
+  T *operator->();
+  T *();
+};
+
+std::string StrFormat_simple() {
+  return absl::StrFormat("Hello");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Hello");
+}
+
+std::string StrFormat_complex(const char *name, double value) {
+  return absl::StrFormat("'%s'='%f'", name, value);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("'{}'='{:f}'", name, value);
+}
+
+std::string StrFormat_integer_conversions() {
+  return absl::StrFormat("int:%d int:%d char:%c char:%c", 65, 'A', 66, 'B');
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("int:{} int:{:d} char:{:c} char:{}", 65, 
'A', 66, 'B');
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_no_newline_removal() {
+  return absl::StrFormat("a line\n");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("a line\n");
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_cstr_removal(const std::string , const std::string 
*s2) {
+  return absl::StrFormat("%s %s %s %s", s1.c_str(), s1.data(), s2->c_str(), 
s2->data());
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("{} {} {} {}", s1, s1, *s2, *s2);
+}
+
+std::string StrFormat_strict_conversion() {
+  const unsigned char uc = 'A';
+  return absl::StrFormat("Integer %hhd from unsigned char\n", uc);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Integer {} from unsigned char\n", uc);
+}
+
+std::string StrFormat_field_width_and_precision() {
+  auto s1 = absl::StrFormat("width only:%*d width and precision:%*.*f 
precision only:%.*f", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width only:{:{}} width and precision:{:{}.{}f} 
precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
+
+  auto s2 = absl::StrFormat("width and precision positional:%1$*2$.*3$f 
after", 3.14159265358979323846, 4, 2);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width and precision positional:{0:{1}.{2}f} 
after", 3.14159265358979323846, 4, 2);
+
+  const int width = 10, precision = 3;
+  const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
+  auto s3 = absl::StrFormat("casts width only:%*d width and precision:%*.*d 
precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES-NOTSTRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
+  // CHECK-FIXES-STRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", static_cast(ui1), 3, 
static_cast(ui2), 4, 2, static_cast(ui3), 5);
+
+  auto s4 = absl::StrFormat("c_str removal width only:%*s width and 
precision:%*.*s precision only:%.*s", 3, s1.c_str(), 4, 2, s2.c_str(), 5, 
s3.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("c_str removal width only:{:>{}} width and 
precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
+
+  const std::string *ps1 = , *ps2 = , *ps3 = 
+  auto s5 = absl::StrFormat("c_str() removal pointer width only:%-*s width and 
precision:%-*.*s precision only:%-.*s", 3, ps1->c_str(), 4, 2, 

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,84 @@
+.. title:: clang-tidy - modernize-use-std-format
+
+modernize-use-std-format
+
+
+Converts calls to ``absl::StrFormat``, or other functions via
+configuration options, to C++20's ``std::format``, or another function
+via a configuration option, modifying the format string appropriately and
+removing now-unnecessary calls to ``std::string::c_str()`` and
+``std::string::data()``.
+
+For example, it turns lines like
+
+.. code-block:: c++
+
+  return absl::StrFormat("The %s is %3d\n", description.c_str(), value);

mikecrowe wrote:

The newline in the format string here should be removed since it isn't present 
in the format string on line 22 below.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-05-02 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,97 @@
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: true}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: false}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+#include 
+// CHECK-FIXES: #include 
+
+namespace absl
+{
+// Use const char * for the format since the real type is hard to mock up.
+template 
+std::string StrFormat(const char *format, const Args&... args);
+} // namespace absl
+
+template 
+struct iterator {
+  T *operator->();
+  T *();
+};
+
+std::string StrFormat_simple() {
+  return absl::StrFormat("Hello");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Hello");
+}
+
+std::string StrFormat_complex(const char *name, double value) {
+  return absl::StrFormat("'%s'='%f'", name, value);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("'{}'='{:f}'", name, value);
+}
+
+std::string StrFormat_integer_conversions() {
+  return absl::StrFormat("int:%d int:%d char:%c char:%c", 65, 'A', 66, 'B');
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("int:{} int:{:d} char:{:c} char:{}", 65, 
'A', 66, 'B');
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_no_newline_removal() {
+  return absl::StrFormat("a line\n");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("a line\n");
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_cstr_removal(const std::string , const std::string 
*s2) {
+  return absl::StrFormat("%s %s %s %s", s1.c_str(), s1.data(), s2->c_str(), 
s2->data());
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("{} {} {} {}", s1, s1, *s2, *s2);
+}
+
+std::string StrFormat_strict_conversion() {
+  const unsigned char uc = 'A';
+  return absl::StrFormat("Integer %hhd from unsigned char\n", uc);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Integer {} from unsigned char\n", uc);
+}
+
+std::string StrFormat_field_width_and_precision() {
+  auto s1 = absl::StrFormat("width only:%*d width and precision:%*.*f 
precision only:%.*f", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width only:{:{}} width and precision:{:{}.{}f} 
precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
+
+  auto s2 = absl::StrFormat("width and precision positional:%1$*2$.*3$f 
after", 3.14159265358979323846, 4, 2);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width and precision positional:{0:{1}.{2}f} 
after", 3.14159265358979323846, 4, 2);
+
+  const int width = 10, precision = 3;
+  const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
+  auto s3 = absl::StrFormat("casts width only:%*d width and precision:%*.*d 
precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES-NOTSTRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
+  // CHECK-FIXES-STRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", static_cast(ui1), 3, 
static_cast(ui2), 4, 2, static_cast(ui3), 5);
+
+  auto s4 = absl::StrFormat("c_str removal width only:%*s width and 
precision:%*.*s precision only:%.*s", 3, s1.c_str(), 4, 2, s2.c_str(), 5, 
s3.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("c_str removal width only:{:>{}} width and 
precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
+
+  const std::string *ps1 = , *ps2 = , *ps3 = 
+  auto s5 = absl::StrFormat("c_str() removal pointer width only:%-*s width and 
precision:%-*.*s precision only:%-.*s", 3, ps1->c_str(), 4, 2, ps2->c_str(), 

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-30 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 01/11] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-30 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 01/10] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-30 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 1/9] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-30 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,107 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  StrFormatLikeFunctions(utils::options::parseStringList(
+  Options.get("StrFormatLikeFunctions", ""))),
+  ReplacementFormatFunction(
+  Options.get("ReplacementFormatFunction", "std::format")),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()),
+  MaybeHeaderToInclude(Options.get("FormatHeader")) {
+  if (StrFormatLikeFunctions.empty())
+StrFormatLikeFunctions.push_back("absl::StrFormat");
+
+  if (!MaybeHeaderToInclude && ReplacementFormatFunction == "std::format")
+MaybeHeaderToInclude = "";
+}
+
+void UseStdFormatCheck::registerPPCallbacks(const SourceManager ,
+Preprocessor *PP,
+Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
+  .bind("strformat"),
+  this);
+}
+
+void UseStdFormatCheck::storeOptions(ClangTidyOptions::OptionMap ) {
+  using utils::options::serializeStringList;
+  Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "StrFormatLikeFunctions",
+serializeStringList(StrFormatLikeFunctions));
+  Options.store(Opts, "ReplacementFormatFunction", ReplacementFormatFunction);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  if (MaybeHeaderToInclude)
+Options.store(Opts, "FormatHeader", *MaybeHeaderToInclude);
+}
+
+void UseStdFormatCheck::check(const MatchFinder::MatchResult ) {
+  const unsigned FormatArgOffset = 0;
+  const auto *OldFunction = Result.Nodes.getNodeAs("func_decl");
+  const auto *StrFormat = Result.Nodes.getNodeAs("strformat");
+
+  utils::FormatStringConverter::Configuration ConverterConfig;
+  ConverterConfig.StrictMode = StrictMode;
+  utils::FormatStringConverter Converter(Result.Context, StrFormat,
+ FormatArgOffset, ConverterConfig,
+ getLangOpts());
+  const Expr *StrFormatCall = StrFormat->getCallee();
+  if (!Converter.canApply()) {
+DiagnosticBuilder Diag = diag(StrFormat->getBeginLoc(),
+  "unable to use '%0' instead of %1 because 
%2")

mikecrowe wrote:

Yes. I can't say that I particularly like the situation and if I should be 
using a different method to get the function name then I'd be happy to change 
it. If someone changes that behaviour in the future then the lit tests will all 
start failing so they will be alerted to the need to do something.

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-29 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe edited 
https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-29 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,107 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  StrFormatLikeFunctions(utils::options::parseStringList(
+  Options.get("StrFormatLikeFunctions", ""))),
+  ReplacementFormatFunction(
+  Options.get("ReplacementFormatFunction", "std::format")),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()),
+  MaybeHeaderToInclude(Options.get("FormatHeader")) {
+  if (StrFormatLikeFunctions.empty())
+StrFormatLikeFunctions.push_back("absl::StrFormat");
+
+  if (!MaybeHeaderToInclude && ReplacementFormatFunction == "std::format")
+MaybeHeaderToInclude = "";
+}
+
+void UseStdFormatCheck::registerPPCallbacks(const SourceManager ,
+Preprocessor *PP,
+Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
+  .bind("strformat"),
+  this);
+}
+
+void UseStdFormatCheck::storeOptions(ClangTidyOptions::OptionMap ) {
+  using utils::options::serializeStringList;
+  Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "StrFormatLikeFunctions",
+serializeStringList(StrFormatLikeFunctions));
+  Options.store(Opts, "ReplacementFormatFunction", ReplacementFormatFunction);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  if (MaybeHeaderToInclude)
+Options.store(Opts, "FormatHeader", *MaybeHeaderToInclude);
+}
+
+void UseStdFormatCheck::check(const MatchFinder::MatchResult ) {
+  const unsigned FormatArgOffset = 0;
+  const auto *OldFunction = Result.Nodes.getNodeAs("func_decl");
+  const auto *StrFormat = Result.Nodes.getNodeAs("strformat");
+
+  utils::FormatStringConverter::Configuration ConverterConfig;
+  ConverterConfig.StrictMode = StrictMode;
+  utils::FormatStringConverter Converter(Result.Context, StrFormat,
+ FormatArgOffset, ConverterConfig,
+ getLangOpts());
+  const Expr *StrFormatCall = StrFormat->getCallee();
+  if (!Converter.canApply()) {
+DiagnosticBuilder Diag = diag(StrFormat->getBeginLoc(),
+  "unable to use '%0' instead of %1 because 
%2")

mikecrowe wrote:

The use of `OldFunction->getIdentifier()` means that the string passed for `%1` 
is already surrounded by quotes. You can see this in the lit test strings:
```
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
```

https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-28 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  StrFormatLikeFunctions(utils::options::parseStringList(
+  Options.get("StrFormatLikeFunctions", ""))),
+  ReplacementFormatFunction(
+  Options.get("ReplacementFormatFunction", "std::format")),
+  IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+   utils::IncludeSorter::IS_LLVM),
+  areDiagsSelfContained()),
+  MaybeHeaderToInclude(Options.get("FormatHeader")) {
+  if (StrFormatLikeFunctions.empty())
+StrFormatLikeFunctions.push_back("absl::StrFormat");
+
+  if (!MaybeHeaderToInclude && ReplacementFormatFunction == "std::format")
+MaybeHeaderToInclude = "";
+}
+
+void UseStdFormatCheck::registerPPCallbacks(const SourceManager ,
+Preprocessor *PP,
+Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(argumentCountAtLeast(1),
+   hasArgument(0, stringLiteral(isOrdinary())),
+   callee(functionDecl(unless(cxxMethodDecl()),
+   matchers::matchesAnyListedName(
+   StrFormatLikeFunctions))
+  .bind("func_decl")))
+  .bind("strformat"),
+  this);
+}
+
+void UseStdFormatCheck::storeOptions(ClangTidyOptions::OptionMap ) {
+  using utils::options::serializeStringList;
+  Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "StrFormatLikeFunctions",
+serializeStringList(StrFormatLikeFunctions));
+  Options.store(Opts, "ReplacementFormatFunction", ReplacementFormatFunction);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  if (MaybeHeaderToInclude)
+Options.store(Opts, "FormatHeader", *MaybeHeaderToInclude);
+}
+
+void UseStdFormatCheck::check(const MatchFinder::MatchResult ) {
+  const unsigned FormatArgOffset = 0;
+  const auto *OldFunction = Result.Nodes.getNodeAs("func_decl");
+  const auto *StrFormat = Result.Nodes.getNodeAs("strformat");
+
+  utils::FormatStringConverter::Configuration ConverterConfig;
+  ConverterConfig.StrictMode = StrictMode;
+  utils::FormatStringConverter Converter(Result.Context, StrFormat,
+ FormatArgOffset, ConverterConfig,
+ getLangOpts());
+  const Expr *StrFormatCall = StrFormat->getCallee();
+  if (!Converter.canApply()) {
+DiagnosticBuilder Diag = diag(StrFormat->getBeginLoc(),
+  "unable to use '%0' instead of %1 because 
%2")
+ << ReplacementFormatFunction
+ << OldFunction->getIdentifier()
+ << Converter.conversionNotPossibleReason();
+return;
+  }
+
+  DiagnosticBuilder Diag =
+  diag(StrFormatCall->getBeginLoc(), "use '%0' instead of %1")
+  << ReplacementFormatFunction << OldFunction->getIdentifier();

mikecrowe wrote:

It's been a while, but I think that was intentional. Just using `OldFunction` 
includes the template arguments which results in unnecessarily-specific warning 
messages like
`warning: use 'fmt::format' instead of 'sprintf' 
[modernize-use-std-format]`
and `warning: use 'std::format' instead of 'StrFormat' 
[modernize-use-std-format]`. Whereas using `OldFunction->getIdentifier()` 
results in the more readable `warning: use 'fmt::format' instead of 'sprintf' 
[modernize-use-std-format]` and `warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]`.

Ideally these messages would say `warning: use 'fmt::format' instead of 
'fmt::sprintf' [modernize-use-std-format]` and `warning: use 'std::format' 
instead of 'absl::StrFormat' [modernize-use-std-format]` (i.e. qualifying 
`OldFunction` 

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-28 Thread Mike Crowe via cfe-commits


@@ -0,0 +1,97 @@
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: true}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+// RUN: %check_clang_tidy \
+// RUN:   -std=c++20 %s modernize-use-std-format %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: false}]}" \
+// RUN:   -- -isystem %clang_tidy_headers
+#include 
+// CHECK-FIXES: #include 
+
+namespace absl
+{
+// Use const char * for the format since the real type is hard to mock up.
+template 
+std::string StrFormat(const char *format, const Args&... args);
+} // namespace absl
+
+template 
+struct iterator {
+  T *operator->();
+  T *();
+};
+
+std::string StrFormat_simple() {
+  return absl::StrFormat("Hello");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Hello");
+}
+
+std::string StrFormat_complex(const char *name, double value) {
+  return absl::StrFormat("'%s'='%f'", name, value);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("'{}'='{:f}'", name, value);
+}
+
+std::string StrFormat_integer_conversions() {
+  return absl::StrFormat("int:%d int:%d char:%c char:%c", 65, 'A', 66, 'B');
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("int:{} int:{:d} char:{:c} char:{}", 65, 
'A', 66, 'B');
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_no_newline_removal() {
+  return absl::StrFormat("a line\n");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("a line\n");
+}
+
+// FormatConverter is capable of removing newlines from the end of the format
+// string. Ensure that isn't incorrectly happening for std::format.
+std::string StrFormat_cstr_removal(const std::string , const std::string 
*s2) {
+  return absl::StrFormat("%s %s %s %s", s1.c_str(), s1.data(), s2->c_str(), 
s2->data());
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("{} {} {} {}", s1, s1, *s2, *s2);
+}
+
+std::string StrFormat_strict_conversion() {
+  const unsigned char uc = 'A';
+  return absl::StrFormat("Integer %hhd from unsigned char\n", uc);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: return std::format("Integer {} from unsigned char\n", uc);
+}
+
+std::string StrFormat_field_width_and_precision() {
+  auto s1 = absl::StrFormat("width only:%*d width and precision:%*.*f 
precision only:%.*f", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width only:{:{}} width and precision:{:{}.{}f} 
precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
+
+  auto s2 = absl::StrFormat("width and precision positional:%1$*2$.*3$f 
after", 3.14159265358979323846, 4, 2);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("width and precision positional:{0:{1}.{2}f} 
after", 3.14159265358979323846, 4, 2);
+
+  const int width = 10, precision = 3;
+  const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
+  auto s3 = absl::StrFormat("casts width only:%*d width and precision:%*.*d 
precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES-NOTSTRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
+  // CHECK-FIXES-STRICT: std::format("casts width only:{:{}} width and 
precision:{:{}.{}} precision only:{:.{}}", static_cast(ui1), 3, 
static_cast(ui2), 4, 2, static_cast(ui3), 5);
+
+  auto s4 = absl::StrFormat("c_str removal width only:%*s width and 
precision:%*.*s precision only:%.*s", 3, s1.c_str(), 4, 2, s2.c_str(), 5, 
s3.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 
'StrFormat' [modernize-use-std-format]
+  // CHECK-FIXES: std::format("c_str removal width only:{:>{}} width and 
precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
+
+  const std::string *ps1 = , *ps2 = , *ps3 = 
+  auto s5 = absl::StrFormat("c_str() removal pointer width only:%-*s width and 
precision:%-*.*s precision only:%-.*s", 3, ps1->c_str(), 4, 2, ps2->c_str(), 

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-28 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 1/8] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-28 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe updated 
https://github.com/llvm/llvm-project/pull/90397

>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH 1/2] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+AST_MATCHER(StringLiteral, isOrdinary) { return Node.isOrdinary(); }
+} // namespace
+
+UseStdFormatCheck::UseStdFormatCheck(StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictMode(Options.getLocalOrGlobal("StrictMode", false)),
+  

[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-28 Thread Mike Crowe via cfe-commits

mikecrowe wrote:

This check was originally proposed and reviewed at 
https://reviews.llvm.org/D154287 last year but never landed since I did not 
(and still do not) have commit access. Near the end of that review, @PiotrZSL 
wrote:
> To be honest, I do not see to much use case for this check. But that's fine.

which may mean that it should not land. I've created this pull request for 
discoverability by those looking for such a check since Phabricator is no 
longer used.


https://github.com/llvm/llvm-project/pull/90397
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)

2024-04-28 Thread Mike Crowe via cfe-commits

https://github.com/mikecrowe created 
https://github.com/llvm/llvm-project/pull/90397

Add a new clang-tidy check that converts absl::StrFormat (and similar 
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate 
Configuration class so that we don't risk confusion by passing two boolean 
configuration parameters into the constructor. Add AllowTrailingNewlineRemoval 
option since we never want to remove trailing newlines in this check.


>From 0d6ede5d59cc70d803bfe2c7997737c1be358c75 Mon Sep 17 00:00:00 2001
From: Mike Crowe 
Date: Sun, 28 Apr 2024 12:41:46 +0100
Subject: [PATCH] [clang-tidy] Add modernize-use-std-format check

Add a new clang-tidy check that converts absl::StrFormat (and similar
functions) to std::format (and similar functions.)

Split the configuration of FormatStringConverter out to a separate
Configuration class so that we don't risk confusion by passing two
boolean configuration parameters into the constructor. Add
AllowTrailingNewlineRemoval option since we never want to remove
trailing newlines in this check.

Differential Revision: https://reviews.llvm.org/D154287
---
 .../clang-tidy/modernize/CMakeLists.txt   |   1 +
 .../modernize/ModernizeTidyModule.cpp |   2 +
 .../modernize/UseStdFormatCheck.cpp   | 108 ++
 .../clang-tidy/modernize/UseStdFormatCheck.h  |  50 
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |   5 +-
 .../utils/FormatStringConverter.cpp   |  10 +-
 .../clang-tidy/utils/FormatStringConverter.h  |   9 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   9 ++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/modernize/use-std-format.rst   |  84 ++
 .../modernize/use-std-format-custom.cpp   |  76 
 .../checkers/modernize/use-std-format-fmt.cpp |  37 ++
 .../checkers/modernize/use-std-format.cpp |  97 
 13 files changed, 483 insertions(+), 6 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-format.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-fmt.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 8005d6e91c060c..576805c4c7f181 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyModernizeModule
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
   UseStartsEndsWithCheck.cpp
+  UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 776558433c5baa..b9c7a2dc383e88 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseStartsEndsWithCheck.h"
+#include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
@@ -76,6 +77,7 @@ class ModernizeModule : public ClangTidyModule {
 "modernize-use-designated-initializers");
 CheckFactories.registerCheck(
 "modernize-use-starts-ends-with");
+
CheckFactories.registerCheck("modernize-use-std-format");
 CheckFactories.registerCheck(
 "modernize-use-std-numbers");
 CheckFactories.registerCheck("modernize-use-std-print");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
new file mode 100644
index 00..d22ebe857cf415
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
@@ -0,0 +1,108 @@
+//===--- UseStdFormatCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UseStdFormatCheck.h"
+#include "../utils/FormatStringConverter.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+