[clang-tools-extra] [clang-tidy] Generate valid JSON for characters that require escaping (PR #187454)
Zeyi Xu via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 20 08:44:08 PDT 2026
https://github.com/zeyi2 updated https://github.com/llvm/llvm-project/pull/187454
>From 814e14cf81dbcf8d4788c7d0665d06926cf61148 Mon Sep 17 00:00:00 2001
From: mtx <mitchell.xu2 at gmail.com>
Date: Thu, 19 Mar 2026 16:00:10 +0800
Subject: [PATCH 1/5] ~
---
.../infrastructure/clang-tidy-store-check-profile-one-tu.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
index 192fbf546d203..9800881af9292 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
@@ -1,9 +1,11 @@
// RUN: rm -rf %t.dir/out
// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%t.dir/out %s -- 2>&1 | not FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-CONSOLE %s
// RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s
+// RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | %python -c "import sys, json; json.load(sys.stdin)"
// RUN: rm -rf %t.dir/out
// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%t.dir/out %s -- 2>&1
// RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s
+// RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | %python -c "import sys, json; json.load(sys.stdin)"
// CHECK-CONSOLE-NOT: ===-------------------------------------------------------------------------===
// CHECK-CONSOLE-NOT: {{.*}} --- Name ---
>From 49571fc2ae37ec6798f993d37b3ff7cf13de732d Mon Sep 17 00:00:00 2001
From: mtx <mitchell.xu2 at gmail.com>
Date: Thu, 19 Mar 2026 16:23:22 +0800
Subject: [PATCH 2/5] OK, add fix
---
.../clang-tidy/ClangTidyProfiling.cpp | 24 +++++++++++++------
clang-tools-extra/docs/ReleaseNotes.rst | 3 +++
2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
index 68b8ae0797acc..1e69d28afea54 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
@@ -45,13 +45,23 @@ void ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS,
void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,
llvm::TimerGroup &TG) {
assert(Storage && "We should have a filename.");
- OS << "{\n";
- OS << R"("file": ")" << Storage->SourceFilename << "\",\n";
- OS << R"("timestamp": ")" << Storage->Timestamp << "\",\n";
- OS << "\"profile\": {\n";
- TG.printJSONValues(OS, "");
- OS << "\n}\n";
- OS << "}\n";
+ std::string TimestampStr;
+ llvm::raw_string_ostream TmpOS(TimestampStr);
+ TmpOS << Storage->Timestamp;
+
+ llvm::json::OStream JOS(OS, 2);
+ JOS.object([&] {
+ JOS.attribute("file", Storage->SourceFilename);
+ JOS.attribute("timestamp", TimestampStr);
+ JOS.attributeBegin("profile");
+ JOS.rawValue([&](llvm::raw_ostream &ROS) {
+ ROS << "{\n";
+ TG.printJSONValues(ROS, "");
+ ROS << "\n}";
+ });
+ JOS.attributeEnd();
+ });
+ OS << "\n";
OS.flush();
}
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 077335c16c331..eafa5883c099e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -102,6 +102,9 @@ Improvements to clang-tidy
manages the creation of temporary header files and ensures that diagnostics
and fixes are verified for the specified headers.
+- Improved :program:`clang-tidy` ``-store-check-profile`` by generating valid
+ JSON when the source file path contains characters that require JSON escaping.
+
New checks
^^^^^^^^^^
>From e4a79f90d4b0d0cd7e33a69a041add1513f49a0c Mon Sep 17 00:00:00 2001
From: mtx <mitchell.xu2 at gmail.com>
Date: Thu, 19 Mar 2026 17:11:25 +0800
Subject: [PATCH 3/5] fixup
---
clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
index 1e69d28afea54..37b3c4f0a00a1 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
@@ -9,6 +9,7 @@
#include "ClangTidyProfiling.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
@@ -44,7 +45,8 @@ void ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS,
void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,
llvm::TimerGroup &TG) {
- assert(Storage && "We should have a filename.");
+ if (!Storage)
+ return;
std::string TimestampStr;
llvm::raw_string_ostream TmpOS(TimestampStr);
TmpOS << Storage->Timestamp;
>From 7ac13dbe4cdf9d4902b10f929864329479b87339 Mon Sep 17 00:00:00 2001
From: mtx <mitchell.xu2 at gmail.com>
Date: Fri, 20 Mar 2026 15:01:00 +0800
Subject: [PATCH 4/5] let's try assert again
---
clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
index 37b3c4f0a00a1..12094d3963cdc 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
@@ -45,8 +45,7 @@ void ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS,
void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,
llvm::TimerGroup &TG) {
- if (!Storage)
- return;
+ assert(Storage && "We should have a filename.");
std::string TimestampStr;
llvm::raw_string_ostream TmpOS(TimestampStr);
TmpOS << Storage->Timestamp;
>From 7698e5303e05e1cb1ecbce655a92cc92c0f32bb0 Mon Sep 17 00:00:00 2001
From: mtx <mitchell.xu2 at gmail.com>
Date: Fri, 20 Mar 2026 23:43:42 +0800
Subject: [PATCH 5/5] try
---
clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
index 12094d3963cdc..9b593367657b6 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
@@ -48,6 +48,7 @@ void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,
assert(Storage && "We should have a filename.");
std::string TimestampStr;
llvm::raw_string_ostream TmpOS(TimestampStr);
+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
TmpOS << Storage->Timestamp;
llvm::json::OStream JOS(OS, 2);
More information about the cfe-commits
mailing list