Skip to content

Commit e0f26a8

Browse files
authored
Fix stdexec regressions (#59)
We may substitute _Fn::template __f (a dependent template name) into a template-template parameter name, when building a parameter mapping. They can't have the same NNSLoc, so the assertion doesn't hold. Also we missed a case when profiling the concept, as in InjectedClassNameType.
1 parent 2db8a37 commit e0f26a8

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

clang/lib/AST/TemplateBase.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,11 @@ TemplateArgumentLoc::TemplateArgumentLoc(ASTContext &Ctx,
606606
LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
607607
assert(Argument.getKind() == TemplateArgument::Template ||
608608
Argument.getKind() == TemplateArgument::TemplateExpansion);
609-
assert(QualifierLoc.getNestedNameSpecifier() ==
610-
Argument.getAsTemplateOrTemplatePattern().getQualifier());
609+
// We can't assume QualifierLoc.getNestedNameSpecifier() ==
610+
// Argument.getAsTemplateOrTemplatePattern().getQualifier() at this point,
611+
// because in template rewriting, we may substitute a DependentTemplateName
612+
// (which has a NNSLoc) into a template template parameter (which
613+
// doesn't have a NNSLoc).
611614
}
612615

613616
NestedNameSpecifierLoc TemplateArgumentLoc::getTemplateQualifierLoc() const {

clang/lib/Sema/SemaConcept.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
307307

308308
namespace {
309309

310+
// FIXME: Convert it to DynamicRecursiveASTVisitor
310311
class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
311312
using inherited = RecursiveASTVisitor<HashParameterMapping>;
312313
friend inherited;
@@ -390,6 +391,20 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
390391
return TraverseType(TL.getType(), TraverseQualifier);
391392
}
392393

394+
bool TraverseTagType(const TagType *T, bool TraverseQualifier) {
395+
// T's parent can be dependent while T doesn't have any template arguments.
396+
// We should have already traversed its qualifier.
397+
// FIXME: Add an assert to catch cases where we failed to profile the
398+
// concept. assert(!T->isDependentType() && "We missed a case in profiling
399+
// concepts!");
400+
return true;
401+
}
402+
403+
bool TraverseInjectedClassNameType(InjectedClassNameType *T,
404+
bool TraverseQualifier) {
405+
return TraverseTemplateArguments(T->getTemplateArgs(SemaRef.Context));
406+
}
407+
393408
bool TraverseTemplateArgument(const TemplateArgument &Arg) {
394409
if (!Arg.containsUnexpandedParameterPack() || Arg.isPackExpansion()) {
395410
// Act as if we are fully expanding this pack, if it is a PackExpansion.

clang/test/SemaTemplate/concepts.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,3 +1266,25 @@ template <class Tb, class Ub> concept A42b = Void<Tb> || A42<Ub>;
12661266
template <class Tc> concept R42c = A42b<Tc, Tc&>;
12671267
static_assert (R42c<void>);
12681268
}
1269+
1270+
namespace parameter_mapping_regressions {
1271+
1272+
namespace case1 {
1273+
1274+
template <template <class> class> using __meval = struct __q;
1275+
template <template <class> class _Tp>
1276+
concept __mvalid = requires { typename __meval<_Tp>; };
1277+
template <class _Fn>
1278+
concept __minvocable = __mvalid<_Fn::template __f>;
1279+
template <class...> struct __mdefer_;
1280+
template <class _Fn, class... _Args>
1281+
requires __minvocable<_Fn>
1282+
struct __mdefer_<_Fn, _Args...> {};
1283+
template <class = __q> struct __mtransform {
1284+
template <class> using __f = int;
1285+
};
1286+
struct __completion_domain_or_none_ : __mdefer_<__mtransform<>> {};
1287+
1288+
}
1289+
1290+
}

0 commit comments

Comments
 (0)