https://github.com/Lu4nScr1pt1ng updated https://github.com/llvm/llvm-project/pull/207793
>From 0e514541e3bb7ae4f20b67b79a2dbcf901cf0cf1 Mon Sep 17 00:00:00 2001 From: Lu4nScr1pt1ng <[email protected]> Date: Mon, 6 Jul 2026 14:48:08 -0300 Subject: [PATCH 1/7] [analyzer] Fix invalid HTML nesting in reports when tags close at end of line AddLineNumber inserted the row-closing </td></tr> with InsertTextBefore, which places it in front of previously inserted text at the same offset. When a variable with a variable_popup was the last token on a source line, the popup's closing </table></span> tags (and the arrow anchor </span> tags) were pushed outside the table row, producing malformed HTML that parsers and validators reject. Insert </td></tr> with InsertTextAfter instead, so tags closing at the end-of-line offset stay inside the row. To keep the message bubbles outside the code rows, add the line number table before processing the path pieces and insert the bubbles after the newline, between the current and the next row. Fixes #46089 --- clang/lib/Rewrite/HTMLRewrite.cpp | 2 +- .../StaticAnalyzer/Core/HTMLDiagnostics.cpp | 13 +++++---- .../html_diagnostics/variable-popups-eol.c | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 clang/test/Analysis/html_diagnostics/variable-popups-eol.c diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp index 109cdf990543a..37fea7118c91f 100644 --- a/clang/lib/Rewrite/HTMLRewrite.cpp +++ b/clang/lib/Rewrite/HTMLRewrite.cpp @@ -247,7 +247,7 @@ static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo, RB.InsertTextBefore(B, OS.str()); } else { RB.InsertTextBefore(B, OS.str()); - RB.InsertTextBefore(E, "</td></tr>"); + RB.InsertTextAfter(E, "</td></tr>"); } } diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index 77c1cceb60fe2..04829bffeecd9 100644 --- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -786,6 +786,10 @@ static void HandlePopUpPieceEndTag(Rewriter &R, void HTMLDiagnostics::RewriteFile(Rewriter &R, const PathPieces &path, FileID FID) { + // Add line numbers first, so that tags inserted later at end-of-line + // offsets (e.g. pop-up closing tags) end up inside the row. + html::EscapeText(R, FID); + html::AddLineNumbers(R, FID); // Process the path. // Maintain the counts of extra note pieces separately. @@ -877,10 +881,6 @@ void HTMLDiagnostics::RewriteFile(Rewriter &R, const PathPieces &path, // Add the <table> start tag of pop-up pieces based on the stored ranges. HandlePopUpPieceStartTag(R, PopUpRanges); - // Add line numbers, header, footer, etc. - html::EscapeText(R, FID); - html::AddLineNumbers(R, FID); - addArrowSVGs(R, FID, ArrowIndices); // If we have a preprocessor, relex the file and syntax highlight. @@ -1096,8 +1096,11 @@ void HTMLDiagnostics::HandlePiece(Rewriter &R, FileID BugFileID, os << "</div></td></tr>"; - // Insert the new html. + // Insert the new html after the newline, so that the bubble's row lands + // between the current line's row and the next line's row. unsigned DisplayPos = LineEnd - FileStart; + if (LineEnd != FileEnd) + ++DisplayPos; SourceLocation Loc = SM.getLocForStartOfFile(LPosInfo.first).getLocWithOffset(DisplayPos); diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c new file mode 100644 index 0000000000000..ae85534c06e9b --- /dev/null +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -0,0 +1,27 @@ +// RUN: rm -fR %t +// RUN: mkdir %t +// RUN: %clang_analyze_cc1 -analyzer-checker=core \ +// RUN: -analyzer-output=html -o %t -verify %s +// RUN: cat %t/report-*.html | FileCheck %s + +void bar(int); + +void foo(void) { + int a; + int b = 1; + if (b + && 1) + bar(a); // expected-warning{{1st function call argument is an uninitialized value}} +} + +// The variable 'b' is the last token on its line, so the popup's closing +// tags and the row's closing </td></tr> are inserted at the same offset. +// The popup table and the closing </span> must stay inside the row. +// CHECK: <span class='variable'>b +// CHECK-SAME: <table class='variable_popup'><tbody> +// CHECK-SAME: <tr><td valign='top'> +// CHECK-SAME: <div class='PathIndex PathIndexPopUp'>1.1</div> +// CHECK-SAME: </td><td>'b' is 1</td></tr> +// CHECK-SAME: </tbody></table> +// CHECK-SAME: </span> +// CHECK-SAME: </td></tr> >From 23097feff9023ab988b73a83f075d6d7e49789ee Mon Sep 17 00:00:00 2001 From: Luan Rabelo <[email protected]> Date: Wed, 8 Jul 2026 05:55:03 -0300 Subject: [PATCH 2/7] Update clang/test/Analysis/html_diagnostics/variable-popups-eol.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- clang/test/Analysis/html_diagnostics/variable-popups-eol.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c index ae85534c06e9b..fda0b3add1925 100644 --- a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -1,7 +1,6 @@ // RUN: rm -fR %t // RUN: mkdir %t -// RUN: %clang_analyze_cc1 -analyzer-checker=core \ -// RUN: -analyzer-output=html -o %t -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o %t -verify %s // RUN: cat %t/report-*.html | FileCheck %s void bar(int); >From a220b46147c6cdec2270b12c42f61682b37a00c9 Mon Sep 17 00:00:00 2001 From: Luan Rabelo <[email protected]> Date: Wed, 8 Jul 2026 05:55:32 -0300 Subject: [PATCH 3/7] Update clang/test/Analysis/html_diagnostics/variable-popups-eol.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- clang/test/Analysis/html_diagnostics/variable-popups-eol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c index fda0b3add1925..b65bf2ff47770 100644 --- a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -1,7 +1,6 @@ // RUN: rm -fR %t // RUN: mkdir %t // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o %t -verify %s -// RUN: cat %t/report-*.html | FileCheck %s void bar(int); >From acda98861525e9360a68c52b9ac5251a08657804 Mon Sep 17 00:00:00 2001 From: Luan Rabelo <[email protected]> Date: Wed, 8 Jul 2026 05:56:12 -0300 Subject: [PATCH 4/7] Update clang/test/Analysis/html_diagnostics/variable-popups-eol.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- clang/test/Analysis/html_diagnostics/variable-popups-eol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c index b65bf2ff47770..08983ff9af139 100644 --- a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -1,7 +1,6 @@ // RUN: rm -fR %t // RUN: mkdir %t // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o %t -verify %s - void bar(int); void foo(void) { >From e82a4e8134520f2c6ca0959a7e1c47d75c06e484 Mon Sep 17 00:00:00 2001 From: Luan Rabelo <[email protected]> Date: Wed, 8 Jul 2026 05:57:41 -0300 Subject: [PATCH 5/7] Update clang/test/Analysis/html_diagnostics/variable-popups-eol.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- clang/test/Analysis/html_diagnostics/variable-popups-eol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c index 08983ff9af139..c8c5482f51905 100644 --- a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -1,7 +1,6 @@ // RUN: rm -fR %t // RUN: mkdir %t // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o %t -verify %s -void bar(int); void foo(void) { int a; >From bb3737148b9fdb24bde1d29b78c48f14da7f31f6 Mon Sep 17 00:00:00 2001 From: Luan Rabelo <[email protected]> Date: Wed, 8 Jul 2026 05:59:53 -0300 Subject: [PATCH 6/7] Update clang/test/Analysis/html_diagnostics/variable-popups-eol.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- clang/test/Analysis/html_diagnostics/variable-popups-eol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c index c8c5482f51905..4e14cd33bcb11 100644 --- a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -1,7 +1,6 @@ // RUN: rm -fR %t // RUN: mkdir %t // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o %t -verify %s - void foo(void) { int a; int b = 1; >From ed58ede76b0ee37c9d03ef821d30f6c100c8d504 Mon Sep 17 00:00:00 2001 From: Lu4nScr1pt1ng <[email protected]> Date: Wed, 8 Jul 2026 06:29:02 -0300 Subject: [PATCH 7/7] Tighten FileCheck matches and restore lines lost to the GH suggestion bug Each CHECK directive now matches a contiguous fragment, so the popup table must come right after the variable and the closing tags must be adjacent up to </td></tr>. Also restore the FileCheck RUN line and the bar declaration that got deleted when the GH suggestion was applied multiple times. --- .../html_diagnostics/variable-popups-eol.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c index 4e14cd33bcb11..6e6160c92e322 100644 --- a/clang/test/Analysis/html_diagnostics/variable-popups-eol.c +++ b/clang/test/Analysis/html_diagnostics/variable-popups-eol.c @@ -1,6 +1,10 @@ // RUN: rm -fR %t // RUN: mkdir %t // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o %t -verify %s +// RUN: cat %t/report-*.html | FileCheck %s + +void bar(int); + void foo(void) { int a; int b = 1; @@ -11,12 +15,9 @@ void foo(void) { // The variable 'b' is the last token on its line, so the popup's closing // tags and the row's closing </td></tr> are inserted at the same offset. -// The popup table and the closing </span> must stay inside the row. -// CHECK: <span class='variable'>b -// CHECK-SAME: <table class='variable_popup'><tbody> -// CHECK-SAME: <tr><td valign='top'> -// CHECK-SAME: <div class='PathIndex PathIndexPopUp'>1.1</div> -// CHECK-SAME: </td><td>'b' is 1</td></tr> -// CHECK-SAME: </tbody></table> -// CHECK-SAME: </span> -// CHECK-SAME: </td></tr> +// The popup table must immediately follow the variable, and the closing +// </span> tags (variable and control-flow arrow anchors) must stay inside +// the row, before </td></tr>. Each directive below matches contiguously. +// CHECK: <span class='variable'>b<table class='variable_popup'><tbody> +// CHECK-SAME: <tr><td valign='top'><div class='PathIndex PathIndexPopUp'>1.1</div></td><td>'b' is 1</td></tr> +// CHECK-SAME: </tbody></table></span></span></span></td></tr> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
