diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 999e302c02535..8946f1bfc7a95 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -280,6 +280,11 @@ class HashParameterMapping : public RecursiveASTVisitor { if (T->getDepth() >= TemplateArgs.getNumLevels()) return true; + // There might not be a corresponding template argument before substituting + // into the parameter mapping, e.g. a sizeof... expression. + if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex())) + return true; + TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex()); if (T->isParameterPack() && SemaRef.ArgPackSubstIndex) { diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index e5e081ffb9d0f..3b7c138f83364 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++20 -ferror-limit 0 -verify %s +// RUN: %clang_cc1 -std=c++20 -ferror-limit 0 -verify=expected,cxx20 %s +// RUN: %clang_cc1 -std=c++2c -ferror-limit 0 -verify=expected %s namespace PR47043 { template concept True = true; @@ -1405,3 +1406,41 @@ static_assert(!std::is_constructible_v, array>); } } + + +namespace GH162125 { +template +concept true_int = (size, true); + +template +concept true_types = true_int; + +template +concept true_types2 = true_int; // cxx20-warning {{pack indexing is a C++2c extension}} + +template +struct s { + template requires true_types && true_types2 + static void f(T); +}; +void(*test)(int) = &s::f; +} + +namespace GH162125_reversed { +template +concept true_int = (size, true); + +template +concept true_types = true_int; + +template +concept true_types2 = true_int; // cxx20-warning {{pack indexing is a C++2c extension}} + +template +struct s { + template requires true_types && true_types2 + static void f(T); +}; + +void(*test)(int) = &s::f; +}