Skip to content

Commit

Permalink
[concepts] Push a CurContext before substituting into out-of-line con…
Browse files Browse the repository at this point in the history
…straints for comparison (#79985)
  • Loading branch information
zyn0217 committed Jan 31, 2024
1 parent 7155c1e commit ab70ac6
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ Bug Fixes to C++ Support
parameter where we did an incorrect specialization of the initialization of
the default parameter.
Fixes (`#68490 <https://github.com/llvm/llvm-project/issues/68490>`_)
- Addressed an issue where constraints involving injected class types are perceived
distinct from its specialization types.
(`#56482 <https://github.com/llvm/llvm-project/issues/56482>`_)
- Fixed a bug where variables referenced by requires-clauses inside
nested generic lambdas were not properly injected into the constraint scope.
(`#73418 <https://github.com/llvm/llvm-project/issues/73418>`_)
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,10 @@ void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,

TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
switch (D->getKind()) {
case Decl::Kind::CXXRecord:
return cast<CXXRecordDecl>(D)
->getDescribedTemplate()
->getTemplateParameters();
case Decl::Kind::ClassTemplate:
return cast<ClassTemplateDecl>(D)->getTemplateParameters();
case Decl::Kind::ClassTemplateSpecialization: {
Expand Down
14 changes: 13 additions & 1 deletion clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,8 +807,20 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
ScopeForParameters.InstantiatedLocal(PVD, PVD);

std::optional<Sema::CXXThisScopeRAII> ThisScope;
if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext()))

// See TreeTransform::RebuildTemplateSpecializationType. A context scope is
// essential for having an injected class as the canonical type for a template
// specialization type at the rebuilding stage. This guarantees that, for
// out-of-line definitions, injected class name types and their equivalent
// template specializations can be profiled to the same value, which makes it
// possible that e.g. constraints involving C<Class<T>> and C<Class> are
// perceived identical.
std::optional<Sema::ContextRAII> ContextScope;
if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext())) {
ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
ContextScope.emplace(S, const_cast<DeclContext *>(cast<DeclContext>(RD)),
/*NewThisContext=*/false);
}
ExprResult SubstConstr = S.SubstConstraintExprWithoutSatisfaction(
const_cast<clang::Expr *>(ConstrExpr), MLTAL);
if (SFINAE.hasErrorOccurred() || !SubstConstr.isUsable())
Expand Down
23 changes: 23 additions & 0 deletions clang/test/SemaTemplate/concepts-out-of-line-def.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,29 @@ template <class T>
void X<T>::bar(decltype(requires { requires is_not_same_v<T, int>; })) {}
} // namespace GH74314

namespace GH56482 {
template <typename SlotMap>
concept slot_map_has_reserve = true;

template <typename T> struct Slot_map {
constexpr void reserve() const noexcept
requires slot_map_has_reserve<Slot_map>;

constexpr void reserve(int) const noexcept
requires slot_map_has_reserve<Slot_map<T>>;
};

template <typename T>
constexpr void Slot_map<T>::reserve() const noexcept
requires slot_map_has_reserve<Slot_map<T>>
{}

template <typename T>
constexpr void Slot_map<T>::reserve(int) const noexcept
requires slot_map_has_reserve<Slot_map>
{}
} // namespace GH56482

namespace GH74447 {
template <typename T> struct S {
template <typename... U, int V>
Expand Down

0 comments on commit ab70ac6

Please sign in to comment.