llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

Fixes #<!-- -->204178

Mangling `template&lt;typename T&gt; auto f(T t, c&lt;decltype(t)&gt; auto) 
-&gt; s;` asserts with `ParmVarDecl is not visible in current parameter 
environment` when `s` carries an ABI tag, as `std::string` does under 
libstdc++. The invented template parameter's constraint refers to the function 
parameter `t`, and the mangler encodes that reference by its nesting depth, so 
the function's parameter scope has to be entered before the name is mangled. 
`mangleFunctionEncoding` does that in the common case, but when the return type 
has a tag it first mangles the name with a temporary mangler to collect the 
tags in use, and the scope was pushed on the outer mangler after the temporary 
one had already copied its depth state. The temporary mangler saw depth zero. 
Without assertions this didn't crash but produced `fp_` instead of `fL0p_`, a 
symbol GCC doesn't emit and that differs from clang's own mangling of the same 
declaration without the tag.

The scope is now pushed on the mangler that actually mangles the name, the same 
pattern `makeFunctionReturnTypeTags` already uses for its own temporary 
mangler. Both branches of `mangleFunctionEncoding` now establish the same depth 
state before mangling the name, so the tagged and untagged manglings agree and 
the assertion stays as it is.


---
Full diff: https://github.com/llvm/llvm-project/pull/223121.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+6) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+5-3) 
- (modified) clang/test/CodeGenCXX/mangle-concept.cpp (+12) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3cca316a91d4d..6d4cff82d13d5 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -676,6 +676,12 @@ features cannot lower the translation-unit ABI level;
   class with an invalid non-static data member, such as one qualified with an
   address space. (#GH194605)
 
+- Fixed an assertion when mangling an abbreviated function template whose
+  constrained `auto` parameter refers to an earlier parameter (e.g.
+  `template<typename T> auto f(T t, C<decltype(t)> auto) -> S`) and whose
+  return type has an ABI tag, such as a type declared in an `abi_tag` inline
+  namespace like `std::string` under libstdc++. (#GH204178)
+
 #### Bug Fixes to AST Handling
 
 - Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 298f3efbfa221..1e847dc1a55ce 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -871,9 +871,11 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) 
{
   // Output name of the function.
   FunctionEncodingMangler.disableDerivedAbiTags();
 
-  FunctionTypeDepthState Saved = FunctionTypeDepth.push();
+  // Enter the function parameter scope on the mangler that mangles the name.
+  FunctionTypeDepthState EncodingSaved =
+      FunctionEncodingMangler.FunctionTypeDepth.push();
   FunctionEncodingMangler.mangleNameWithAbiTags(FD);
-  FunctionTypeDepth.pop(Saved);
+  FunctionEncodingMangler.FunctionTypeDepth.pop(EncodingSaved);
 
   // Remember length of the function name in the buffer.
   size_t EncodingPositionStart = FunctionEncodingStream.str().size();
@@ -891,7 +893,7 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
       AdditionalAbiTags.end());
 
   // Output name with implicit tags and function encoding from temporary 
buffer.
-  Saved = FunctionTypeDepth.push();
+  FunctionTypeDepthState Saved = FunctionTypeDepth.push();
   mangleNameWithAbiTags(FD, AdditionalAbiTags);
   FunctionTypeDepth.pop(Saved);
   Out << FunctionEncodingStream.str().substr(EncodingPositionStart);
diff --git a/clang/test/CodeGenCXX/mangle-concept.cpp 
b/clang/test/CodeGenCXX/mangle-concept.cpp
index 63e819bb4f8f0..ba900e0cc7522 100644
--- a/clang/test/CodeGenCXX/mangle-concept.cpp
+++ b/clang/test/CodeGenCXX/mangle-concept.cpp
@@ -245,3 +245,15 @@ namespace gh67356 {
   // CHECK: define {{.*}} 
@_ZN7gh673561gIiTkNS_1CIFDTcl1ffL0p_fp_EET_EEEiEEvS3_T0_(
   template void g(int, int);
 }
+
+namespace gh204178 {
+  // Like gh67356::f, but the return type carries an ABI tag.
+  inline namespace [[gnu::abi_tag("n")]] n {
+    class s {};
+  }
+  template<typename, typename> concept c = true;
+  template<typename T> auto f(T t, c<decltype(t)> auto) -> s;
+  // CHECK: call {{.*}} @_ZN8gh2041781fIiTkNS_1cIDtfL0p_EEEiEENS_1n1sET_T0_(
+  // CLANG17: call {{.*}} @_ZN8gh2041781fIiiEENS_1n1sET_T0_(
+  void g() { f(0, 0); }
+}

``````````

</details>


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

Reply via email to