llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Chris Carlon (cjc25)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/202837.diff
2 Files Affected:
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+7)
- (modified) clang/test/SemaTemplate/instantiate-init.cpp (+10)
``````````diff
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 6df6d5505c61c..cede8fc255b16 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,12 @@
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;
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/202837
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits