https://github.com/cjc25 updated 
https://github.com/llvm/llvm-project/pull/202837

>From 34ab6eafd7f0a218fc89236234d812bfa9936c93 Mon Sep 17 00:00:00 2001
From: Chris Carlon <[email protected]>
Date: Tue, 9 Jun 2026 22:16:24 -0400
Subject: [PATCH 1/2] fix(clang): Fix miscompile for string literals.

When a string-literal is used to initialize a sized char array, the
template instantiation code always returned a reference to the string
literal AST node. Therefore modifications to the array bounds applied to
all instantiantions.

This change copies the AST node for each template instantiation, so each
template instantiation gets its own string-literal.

After this change, the compilation behavior matches `g++`:
*   When the array bounds depend on the template parameter, multiple
    copies of the string literal are present in the final binary, even
    with `-O3`
*   When the array bounds do not depend on the template parameter, only
    one copy of the string literal is present in the final binary with
    `-O3`.

I did not check where the dedupe occurs, but it appears to work the same
way in both compilers.

Fixes #72738
---
 clang/lib/Sema/SemaTemplateInstantiate.cpp   |  9 +++++++++
 clang/test/SemaTemplate/instantiate-init.cpp | 10 ++++++++++
 2 files changed, 19 insertions(+)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 6df6d5505c61c..ee9d986bca39a 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1340,6 +1340,7 @@ namespace {
     ExprResult TransformPredefinedExpr(PredefinedExpr *E);
     ExprResult TransformDeclRefExpr(DeclRefExpr *E);
     ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    ExprResult TransformStringLiteral(StringLiteral *E);
 
     ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
                                             NonTypeTemplateParmDecl *D);
@@ -1916,6 +1917,14 @@ 
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
 }
 
+ExprResult
+TemplateInstantiator::TransformStringLiteral(StringLiteral *E) {
+  return StringLiteral::Create(
+      SemaRef.Context, E->getBytes(), E->getKind(), E->isPascal(),
+      E->getType(),
+      llvm::ArrayRef<SourceLocation>(E->tokloc_begin(), E->tokloc_end()));
+}
+
 ExprResult
 TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
                                                NonTypeTemplateParmDecl *NTTP) {
diff --git a/clang/test/SemaTemplate/instantiate-init.cpp 
b/clang/test/SemaTemplate/instantiate-init.cpp
index 5fc3e83114e28..e9c8374559855 100644
--- a/clang/test/SemaTemplate/instantiate-init.cpp
+++ b/clang/test/SemaTemplate/instantiate-init.cpp
@@ -178,3 +178,13 @@ namespace RebuildStdInitList {
   template<typename U> void f() { PES({1, 2, 3}); }
   void g() { f<int>(); }
 }
+
+namespace StringLiteralDefaultInit {
+  template <unsigned L> struct V {
+    char rest[L] = "at least 18 bytes";
+  };
+  void test() {
+    V<100> v1;
+    V<18> v2;
+  }
+}

>From 4996bbc18dd2bb41fc62a4d3ca67cc595671cdf9 Mon Sep 17 00:00:00 2001
From: carlon <[email protected]>
Date: Wed, 10 Jun 2026 07:51:22 -0400
Subject: [PATCH 2/2] fix formatting

---
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index ee9d986bca39a..cede8fc255b16 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1917,11 +1917,9 @@ 
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
 }
 
-ExprResult
-TemplateInstantiator::TransformStringLiteral(StringLiteral *E) {
+ExprResult TemplateInstantiator::TransformStringLiteral(StringLiteral *E) {
   return StringLiteral::Create(
-      SemaRef.Context, E->getBytes(), E->getKind(), E->isPascal(),
-      E->getType(),
+      SemaRef.Context, E->getBytes(), E->getKind(), E->isPascal(), 
E->getType(),
       llvm::ArrayRef<SourceLocation>(E->tokloc_begin(), E->tokloc_end()));
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to