[clang] c743986 - Enter the function parameter mangling scope for a function encoding

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 25 16:19:14 PDT 2023


Author: Richard Smith
Date: 2023-09-25T16:19:02-07:00
New Revision: c74398649f28ab78c74bacfe82e69224377008e7

URL: https://github.com/llvm/llvm-project/commit/c74398649f28ab78c74bacfe82e69224377008e7
DIFF: https://github.com/llvm/llvm-project/commit/c74398649f28ab78c74bacfe82e69224377008e7.diff

LOG: Enter the function parameter mangling scope for a function encoding
before mangling the template argument list.

With an abbreviated function template, the template parameters can
contain constraints that refer to the function parameters, so we need to
bring the function parameters into scope earlier.

Fixes #67356.

Added: 
    

Modified: 
    clang/lib/AST/ItaniumMangle.cpp
    clang/test/CodeGenCXX/mangle-concept.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 4cb1ab56a1e618a..a11dbe22b196e41 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -841,8 +841,17 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
 
   AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD);
   if (ReturnTypeAbiTags.empty()) {
-    // There are no tags for return type, the simplest case.
+    // There are no tags for return type, the simplest case. Enter the function
+    // parameter scope before mangling the name, because a template using
+    // constrained `auto` can have references to its parameters within its
+    // template argument list:
+    //
+    //   template<typename T> void f(T x, C<decltype(x)> auto)
+    // ... is mangled as ...
+    //   template<typename T, C<decltype(param 1)> U> void f(T, U)
+    FunctionTypeDepthState Saved = FunctionTypeDepth.push();
     mangleName(GD);
+    FunctionTypeDepth.pop(Saved);
     mangleFunctionEncodingBareType(FD);
     return;
   }
@@ -855,7 +864,10 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
   CXXNameMangler FunctionEncodingMangler(*this, FunctionEncodingStream);
   // Output name of the function.
   FunctionEncodingMangler.disableDerivedAbiTags();
+
+  FunctionTypeDepthState Saved = FunctionTypeDepth.push();
   FunctionEncodingMangler.mangleNameWithAbiTags(FD, nullptr);
+  FunctionTypeDepth.pop(Saved);
 
   // Remember length of the function name in the buffer.
   size_t EncodingPositionStart = FunctionEncodingStream.str().size();
@@ -873,7 +885,9 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
       AdditionalAbiTags.end());
 
   // Output name with implicit tags and function encoding from temporary buffer.
+  Saved = FunctionTypeDepth.push();
   mangleNameWithAbiTags(FD, &AdditionalAbiTags);
+  FunctionTypeDepth.pop(Saved);
   Out << FunctionEncodingStream.str().substr(EncodingPositionStart);
 
   // Function encoding could create new substitutions so we have to add

diff  --git a/clang/test/CodeGenCXX/mangle-concept.cpp b/clang/test/CodeGenCXX/mangle-concept.cpp
index 391cf09ede8555d..efab169903395ac 100644
--- a/clang/test/CodeGenCXX/mangle-concept.cpp
+++ b/clang/test/CodeGenCXX/mangle-concept.cpp
@@ -228,3 +228,15 @@ namespace gh67244 {
   // CHECK: define {{.*}} @_ZN7gh672441fITkNS_1CIifEEiEEvT_(
   template void f(int);
 }
+
+namespace gh67356 {
+  template<typename, typename T> concept C = true;
+  template<typename T> void f(T t, C<decltype(t)> auto) {}
+  // CHECK: define {{.*}} @_ZN7gh673561fIiTkNS_1CIDtfL0p_EEEiEEvT_T0_(
+  template void f(int, int);
+
+  // Note, we use `fL0p` not `fp` above because:
+  template<typename T> void g(T t, C<auto (T u) -> decltype(f(t, u))> auto) {}
+  // CHECK: define {{.*}} @_ZN7gh673561gIiTkNS_1CIFDTcl1ffL0p_fp_EET_EEEiEEvS3_T0_(
+  template void g(int, int);
+}


        


More information about the cfe-commits mailing list