mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
[Concepts] Fix friend-checking to include NTTPs
More work for temp.friend p9, this fixes a previous bug where we didn't properly consider a friend to depend on the enclosing template if it only did so via an NTTP.
This commit is contained in:
parent
ed4943d560
commit
6c38ffc7b6
@ -1707,6 +1707,18 @@ class ConstraintRefersToContainingTemplateChecker
|
||||
Result = true;
|
||||
}
|
||||
|
||||
void CheckNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
||||
assert(D->getDepth() <= TemplateDepth &&
|
||||
"Nothing should reference a value below the actual template depth, "
|
||||
"depth is likely wrong");
|
||||
if (D->getDepth() != TemplateDepth)
|
||||
Result = true;
|
||||
|
||||
// Necessary because the type of the NTTP might be what refers to the parent
|
||||
// constriant.
|
||||
TransformType(D->getType());
|
||||
}
|
||||
|
||||
public:
|
||||
using inherited = TreeTransform<ConstraintRefersToContainingTemplateChecker>;
|
||||
|
||||
@ -1742,6 +1754,8 @@ public:
|
||||
// unreachable should catch future instances/cases.
|
||||
if (auto *TD = dyn_cast<TypedefNameDecl>(D))
|
||||
TransformType(TD->getUnderlyingType());
|
||||
else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D))
|
||||
CheckNonTypeTemplateParmDecl(NTTPD);
|
||||
else if (auto *VD = dyn_cast<ValueDecl>(D))
|
||||
TransformType(VD->getType());
|
||||
else if (auto *TD = dyn_cast<TemplateDecl>(D))
|
||||
|
@ -411,3 +411,33 @@ namespace RefersToParentInConstraint {
|
||||
S<long> y;
|
||||
}
|
||||
} // namespace RefersToParentInConstraint
|
||||
|
||||
namespace NTTP {
|
||||
struct Base{};
|
||||
template<int N>
|
||||
struct S : Base {
|
||||
// N is from the parent template.
|
||||
template<typename T>
|
||||
friend int templ_func(Base&) requires(N > 0)
|
||||
{ return 10; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct U : Base {
|
||||
template<T N>
|
||||
friend int templ_func(Base&) requires(N>0)
|
||||
{ return 10; }
|
||||
};
|
||||
|
||||
void use() {
|
||||
S<1> s1;
|
||||
templ_func<float>(s1);
|
||||
S<2> s2;
|
||||
templ_func<float>(s2);
|
||||
|
||||
U<int> u1;
|
||||
templ_func<1>(u1);
|
||||
U<short> u2;
|
||||
templ_func<1>(u2);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user