This revision was automatically updated to reflect the committed changes. Closed by commit rG87aa31827b29: [clang] fix concepts crash on substitution failure during normalization (authored by mizvekov).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D106907/new/ https://reviews.llvm.org/D106907 Files: clang/lib/Sema/SemaConcept.cpp clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp Index: clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp =================================================================== --- clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp +++ clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp @@ -67,3 +67,18 @@ static_assert((foo<1>(), true)); } + +namespace PR47174 { +// This checks that we don't crash with a failed substitution on the first constrained argument when +// performing normalization. +template <Bar2 T, True U> +requires true struct S3; // expected-note {{template is declared here}} +template <True T, True U> +requires true struct S3<T, U>; // expected-error {{class template partial specialization is not more specialized than the primary template}} + +// Same as above, for the second position (but this was already working). +template <True T, Bar2 U> +requires true struct S4; // expected-note {{template is declared here}} +template <True T, True U> +requires true struct S4<T, U>; // expected-error {{class template partial specialization is not more specialized than the primary template}} +} // namespace PR47174 Index: clang/lib/Sema/SemaConcept.cpp =================================================================== --- clang/lib/Sema/SemaConcept.cpp +++ clang/lib/Sema/SemaConcept.cpp @@ -742,22 +742,15 @@ NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E) { assert(E.size() != 0); - auto First = fromConstraintExpr(S, D, E[0]); - if (E.size() == 1) - return First; - auto Second = fromConstraintExpr(S, D, E[1]); - if (!Second) + auto Conjunction = fromConstraintExpr(S, D, E[0]); + if (!Conjunction) return None; - llvm::Optional<NormalizedConstraint> Conjunction; - Conjunction.emplace(S.Context, std::move(*First), std::move(*Second), - CCK_Conjunction); - for (unsigned I = 2; I < E.size(); ++I) { + for (unsigned I = 1; I < E.size(); ++I) { auto Next = fromConstraintExpr(S, D, E[I]); if (!Next) - return llvm::Optional<NormalizedConstraint>{}; - NormalizedConstraint NewConjunction(S.Context, std::move(*Conjunction), + return None; + *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction), std::move(*Next), CCK_Conjunction); - *Conjunction = std::move(NewConjunction); } return Conjunction; }
Index: clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp =================================================================== --- clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp +++ clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp @@ -67,3 +67,18 @@ static_assert((foo<1>(), true)); } + +namespace PR47174 { +// This checks that we don't crash with a failed substitution on the first constrained argument when +// performing normalization. +template <Bar2 T, True U> +requires true struct S3; // expected-note {{template is declared here}} +template <True T, True U> +requires true struct S3<T, U>; // expected-error {{class template partial specialization is not more specialized than the primary template}} + +// Same as above, for the second position (but this was already working). +template <True T, Bar2 U> +requires true struct S4; // expected-note {{template is declared here}} +template <True T, True U> +requires true struct S4<T, U>; // expected-error {{class template partial specialization is not more specialized than the primary template}} +} // namespace PR47174 Index: clang/lib/Sema/SemaConcept.cpp =================================================================== --- clang/lib/Sema/SemaConcept.cpp +++ clang/lib/Sema/SemaConcept.cpp @@ -742,22 +742,15 @@ NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E) { assert(E.size() != 0); - auto First = fromConstraintExpr(S, D, E[0]); - if (E.size() == 1) - return First; - auto Second = fromConstraintExpr(S, D, E[1]); - if (!Second) + auto Conjunction = fromConstraintExpr(S, D, E[0]); + if (!Conjunction) return None; - llvm::Optional<NormalizedConstraint> Conjunction; - Conjunction.emplace(S.Context, std::move(*First), std::move(*Second), - CCK_Conjunction); - for (unsigned I = 2; I < E.size(); ++I) { + for (unsigned I = 1; I < E.size(); ++I) { auto Next = fromConstraintExpr(S, D, E[I]); if (!Next) - return llvm::Optional<NormalizedConstraint>{}; - NormalizedConstraint NewConjunction(S.Context, std::move(*Conjunction), + return None; + *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction), std::move(*Next), CCK_Conjunction); - *Conjunction = std::move(NewConjunction); } return Conjunction; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits