Skip to content

Commit e278599

Browse files
committed
[Clang][Sema] fix a bug on constraint check with template friend function
1 parent 8009bbe commit e278599

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ Bug Fixes to C++ Support
627627
- Fix a bug on template partial specialization with issue on deduction of nontype template parameter
628628
whose type is `decltype(auto)`. Fixes (#GH68885).
629629
- Clang now correctly treats the noexcept-specifier of a friend function to be a complete-class context.
630+
- Fix a bug on constraint check with template friend function. Fixes (#GH90349).
630631

631632
Bug Fixes to AST Handling
632633
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,20 @@ Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
281281
if (Function->getPrimaryTemplate()->isMemberSpecialization())
282282
return Response::Done();
283283

284+
if (Function->getFriendObjectKind())
285+
if (const ClassTemplateSpecializationDecl *TD =
286+
dyn_cast<ClassTemplateSpecializationDecl>(
287+
Function->getLexicalDeclContext())) {
288+
const CXXRecordDecl *TemplatePattern =
289+
TD->getTemplateInstantiationPattern();
290+
const FunctionDecl *FunctionPattern =
291+
Function->getTemplateInstantiationPattern();
292+
if (TemplatePattern && FunctionPattern &&
293+
TemplatePattern->getTemplateDepth() ==
294+
FunctionPattern->getTemplateDepth())
295+
return Response::Done();
296+
}
297+
284298
// If this function is a generic lambda specialization, we are done.
285299
if (!ForConstraintInstantiation &&
286300
isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) {

clang/test/SemaCXX/PR90349.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
2+
3+
// expected-no-diagnostics
4+
5+
namespace std {
6+
template<class T>
7+
concept floating_point = __is_same(T,double) || __is_same(T,float);
8+
9+
template<class T>
10+
concept integral = __is_same(T,int);
11+
12+
}
13+
14+
template<std::integral T, std::floating_point Float>
15+
class Blob;
16+
17+
template<std::floating_point Float, std::integral T>
18+
Blob<T, Float> MakeBlob();
19+
20+
template<std::integral T, std::floating_point Float>
21+
class Blob {
22+
private:
23+
Blob() {}
24+
25+
friend Blob<T, Float> MakeBlob<Float, T>();
26+
};
27+
28+
template<std::floating_point Float, std::integral T>
29+
Blob<T, Float> MakeBlob()
30+
{
31+
return Blob<T, Float>();
32+
}
33+
34+
template<std::floating_point Float, std::integral T>
35+
Blob<T, Float> FindBlobs()
36+
{
37+
return MakeBlob<Float, T>();
38+
}
39+
40+
int main(int argc, const char * argv[]) {
41+
FindBlobs<double, int>();
42+
return 0;
43+
}

0 commit comments

Comments
 (0)