hokein created this revision. hokein added a reviewer: rsmith. Herald added a subscriber: kristof.beyls. Herald added a project: clang.
`TemplateTypeParmDecl::hasTypeConstraint` is not a safe guard for checking `TemplateTypeParmDecl::getTypeConstraint()` result is null. in somecases (e.g. implicit deduction guide templates synthesized from the constructor), hasTypeConstraint returns false, and getTypeConstraint returns a nullptr. Fix https://bugs.llvm.org/show_bug.cgi?id=46790 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D84455 Files: clang/lib/Serialization/ASTReaderDecl.cpp clang/test/PCH/cxx2a-constraints-crash.cpp Index: clang/test/PCH/cxx2a-constraints-crash.cpp =================================================================== --- /dev/null +++ clang/test/PCH/cxx2a-constraints-crash.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t +// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s + +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template <typename T, typename U> +concept not_same_as = true; + +template <int Kind> +struct subrange { + template <not_same_as<int> R> + subrange(R) requires(Kind == 0); + + template <not_same_as<int> R> + subrange(R) requires(Kind != 0); +}; + +template <typename R> +subrange(R) -> subrange<42>; + +int main() { + int c; + subrange s(c); +} + +#endif \ No newline at end of file Index: clang/lib/Serialization/ASTReaderDecl.cpp =================================================================== --- clang/lib/Serialization/ASTReaderDecl.cpp +++ clang/lib/Serialization/ASTReaderDecl.cpp @@ -2909,9 +2909,11 @@ return false; if (TX->hasTypeConstraint() != TY->hasTypeConstraint()) return false; - if (TX->hasTypeConstraint()) { - const TypeConstraint *TXTC = TX->getTypeConstraint(); - const TypeConstraint *TYTC = TY->getTypeConstraint(); + const TypeConstraint *TXTC = TX->getTypeConstraint(); + const TypeConstraint *TYTC = TY->getTypeConstraint(); + if (!TXTC != !TYTC) + return false; + if (TXTC && TYTC) { if (TXTC->getNamedConcept() != TYTC->getNamedConcept()) return false; if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs())
Index: clang/test/PCH/cxx2a-constraints-crash.cpp =================================================================== --- /dev/null +++ clang/test/PCH/cxx2a-constraints-crash.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t +// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s + +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template <typename T, typename U> +concept not_same_as = true; + +template <int Kind> +struct subrange { + template <not_same_as<int> R> + subrange(R) requires(Kind == 0); + + template <not_same_as<int> R> + subrange(R) requires(Kind != 0); +}; + +template <typename R> +subrange(R) -> subrange<42>; + +int main() { + int c; + subrange s(c); +} + +#endif \ No newline at end of file Index: clang/lib/Serialization/ASTReaderDecl.cpp =================================================================== --- clang/lib/Serialization/ASTReaderDecl.cpp +++ clang/lib/Serialization/ASTReaderDecl.cpp @@ -2909,9 +2909,11 @@ return false; if (TX->hasTypeConstraint() != TY->hasTypeConstraint()) return false; - if (TX->hasTypeConstraint()) { - const TypeConstraint *TXTC = TX->getTypeConstraint(); - const TypeConstraint *TYTC = TY->getTypeConstraint(); + const TypeConstraint *TXTC = TX->getTypeConstraint(); + const TypeConstraint *TYTC = TY->getTypeConstraint(); + if (!TXTC != !TYTC) + return false; + if (TXTC && TYTC) { if (TXTC->getNamedConcept() != TYTC->getNamedConcept()) return false; if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs())
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits