Author: Richard Smith Date: 2021-05-12T18:45:33-07:00 New Revision: 2f9d8b08ea658b612065cbf7d4b0fbd7f28bb36a
URL: https://github.com/llvm/llvm-project/commit/2f9d8b08ea658b612065cbf7d4b0fbd7f28bb36a DIFF: https://github.com/llvm/llvm-project/commit/2f9d8b08ea658b612065cbf7d4b0fbd7f28bb36a.diff LOG: PR50306: When instantiating a generic lambda with a constrained 'auto', properly track that it has constraints. Previously an instantiation of a constrained generic lambda would behave as if unconstrained because we incorrectly cached a "has no constraints" value that we computed before the constraints from 'auto' parameters were attached. Added: Modified: clang/lib/AST/DeclTemplate.cpp clang/test/SemaTemplate/concepts.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 4b3a4062d642..ba4a5359f937 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -68,12 +68,21 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C, if (!IsPack && TTP->getTemplateParameters()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; - } else if (const TypeConstraint *TC = - cast<TemplateTypeParmDecl>(P)->getTypeConstraint()) { - if (TC->getImmediatelyDeclaredConstraint() - ->containsUnexpandedParameterPack()) - ContainsUnexpandedParameterPack = true; - HasConstrainedParameters = true; + } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) { + // FIXME: The type parameter might have a constraint that has not been + // attached yet. If so, we can compute the wrong value for + // 'ContainsUnexpandedParameterPack' here. Note that this only happens + // for implicit parameters, for which the ParmVarDecl will correctly + // track that it contains an unexpanded parameter pack, so this should + // not be problematic in practice. + if (const TypeConstraint *TC = TTP->getTypeConstraint()) { + if (TC->getImmediatelyDeclaredConstraint() + ->containsUnexpandedParameterPack()) + ContainsUnexpandedParameterPack = true; + } + HasConstrainedParameters = TTP->hasTypeConstraint(); + } else { + llvm_unreachable("unexpcted template parameter type"); } // FIXME: If a default argument contains an unexpanded parameter pack, the // template parameter list does too. diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 2a46dec5afb7..753a84c35e1f 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -65,3 +65,12 @@ namespace P0857R0 { template<typename T> requires C<T> struct Y {}; X<Y> xy; // expected-error {{no template named 'X'}} } + +namespace PR50306 { + template<typename T> concept NotInt = sizeof(T) != sizeof(int); // expected-note {{because}} + template<typename T> void f() { + [](NotInt auto) {}(T()); // expected-error {{no matching function}} expected-note {{constraints not satisfied}} expected-note {{because}} + } + template void f<char>(); // OK + template void f<int>(); // expected-note {{in instantiation of}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits