Skip to content

Commit

Permalink
[Concepts] Fix a deserialization crash.
Browse files Browse the repository at this point in the history
`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, immediately-declared constraint is not formed because of an error),
hasTypeConstraint returns false, and getTypeConstraint returns a nullptr.

Fix https://bugs.llvm.org/show_bug.cgi?id=46790

Differential Revision: https://reviews.llvm.org/D84455

(cherry picked from commit 73c12bd)
  • Loading branch information
hokein authored and zmodem committed Aug 3, 2020
1 parent 3ae25b7 commit a45dd85
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
8 changes: 5 additions & 3 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Expand Up @@ -2912,9 +2912,11 @@ static bool isSameTemplateParameter(const NamedDecl *X,
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())
Expand Down
29 changes: 29 additions & 0 deletions 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

0 comments on commit a45dd85

Please sign in to comment.