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<typename T> auto f(T t, c<decltype(t)> auto) -> 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
