Skip to content

Commit c743986

Browse files
committed
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 llvm#67356.
1 parent 0d7c340 commit c743986

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,17 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
841841

842842
AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD);
843843
if (ReturnTypeAbiTags.empty()) {
844-
// There are no tags for return type, the simplest case.
844+
// There are no tags for return type, the simplest case. Enter the function
845+
// parameter scope before mangling the name, because a template using
846+
// constrained `auto` can have references to its parameters within its
847+
// template argument list:
848+
//
849+
// template<typename T> void f(T x, C<decltype(x)> auto)
850+
// ... is mangled as ...
851+
// template<typename T, C<decltype(param 1)> U> void f(T, U)
852+
FunctionTypeDepthState Saved = FunctionTypeDepth.push();
845853
mangleName(GD);
854+
FunctionTypeDepth.pop(Saved);
846855
mangleFunctionEncodingBareType(FD);
847856
return;
848857
}
@@ -855,7 +864,10 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
855864
CXXNameMangler FunctionEncodingMangler(*this, FunctionEncodingStream);
856865
// Output name of the function.
857866
FunctionEncodingMangler.disableDerivedAbiTags();
867+
868+
FunctionTypeDepthState Saved = FunctionTypeDepth.push();
858869
FunctionEncodingMangler.mangleNameWithAbiTags(FD, nullptr);
870+
FunctionTypeDepth.pop(Saved);
859871

860872
// Remember length of the function name in the buffer.
861873
size_t EncodingPositionStart = FunctionEncodingStream.str().size();
@@ -873,7 +885,9 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) {
873885
AdditionalAbiTags.end());
874886

875887
// Output name with implicit tags and function encoding from temporary buffer.
888+
Saved = FunctionTypeDepth.push();
876889
mangleNameWithAbiTags(FD, &AdditionalAbiTags);
890+
FunctionTypeDepth.pop(Saved);
877891
Out << FunctionEncodingStream.str().substr(EncodingPositionStart);
878892

879893
// Function encoding could create new substitutions so we have to add

clang/test/CodeGenCXX/mangle-concept.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,15 @@ namespace gh67244 {
228228
// CHECK: define {{.*}} @_ZN7gh672441fITkNS_1CIifEEiEEvT_(
229229
template void f(int);
230230
}
231+
232+
namespace gh67356 {
233+
template<typename, typename T> concept C = true;
234+
template<typename T> void f(T t, C<decltype(t)> auto) {}
235+
// CHECK: define {{.*}} @_ZN7gh673561fIiTkNS_1CIDtfL0p_EEEiEEvT_T0_(
236+
template void f(int, int);
237+
238+
// Note, we use `fL0p` not `fp` above because:
239+
template<typename T> void g(T t, C<auto (T u) -> decltype(f(t, u))> auto) {}
240+
// CHECK: define {{.*}} @_ZN7gh673561gIiTkNS_1CIFDTcl1ffL0p_fp_EET_EEEiEEvS3_T0_(
241+
template void g(int, int);
242+
}

0 commit comments

Comments
 (0)