https://github.com/falbrechtskirchinger created https://github.com/llvm/llvm-project/pull/113182
The ASTWriter currently assumes template type constraints to be initialized ((bool)getTypeConstraint() == hasTypeConstraint()). Issues #99036 and #109354 identified a scenario where this assertion is violated. This patch removes the assumption and adds another boolean to the serialization, to explicitly encode whether the type constraint has been initialized. The same issue was incidentally fixed on the main branch by #111179. This solution avoids backporting #111179 and its dependencies. >From 5025d5a08196392afdbc4f328042795ff93073b9 Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger <falbrechtskirchin...@gmail.com> Date: Mon, 21 Oct 2024 12:24:58 +0200 Subject: [PATCH] [Serialization] Handle uninitialized type constraints The ASTWriter currently assumes template type constraints to be initialized ((bool)getTypeConstraint() == hasTypeConstraint()). Issues #99036 and #109354 identified a scenario where this assertion is violated. This patch removes the assumption and adds another boolean to the serialization, to explicitly encode whether the type constraint has been initialized. The same issue was incidentally fixed on the main branch by #111179. This solution avoids backporting #111179 and its dependencies. --- clang/lib/Serialization/ASTReaderDecl.cpp | 3 ++- clang/lib/Serialization/ASTWriterDecl.cpp | 5 +++-- clang/test/PCH/cxx2a-constraints-crash.cpp | 15 +++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index c118f3818467d9..154acdfbe03276 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2665,7 +2665,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); - if (D->hasTypeConstraint()) { + const bool TypeConstraintInitialized = Record.readBool(); + if (TypeConstraintInitialized && D->hasTypeConstraint()) { ConceptReference *CR = nullptr; if (Record.readBool()) CR = Record.readConceptReference(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 8a4ca54349e38f..ff1334340874b2 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1880,7 +1880,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { Record.push_back(D->wasDeclaredWithTypename()); const TypeConstraint *TC = D->getTypeConstraint(); - assert((bool)TC == D->hasTypeConstraint()); + Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr); if (TC) { auto *CR = TC->getConceptReference(); Record.push_back(CR != nullptr); @@ -1898,7 +1898,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { if (OwnsDefaultArg) Record.AddTemplateArgumentLoc(D->getDefaultArgument()); - if (!TC && !OwnsDefaultArg && + if (!D->hasTypeConstraint() && !OwnsDefaultArg && D->getDeclContext() == D->getLexicalDeclContext() && !D->isInvalidDecl() && !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() && @@ -2561,6 +2561,7 @@ void ASTWriter::WriteDeclAbbrevs() { // TemplateTypeParmDecl Abv->Add( BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename + Abv->Add(BitCodeAbbrevOp(0)); // TypeConstraintInitialized Abv->Add(BitCodeAbbrevOp(0)); // OwnsDefaultArg DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv)); diff --git a/clang/test/PCH/cxx2a-constraints-crash.cpp b/clang/test/PCH/cxx2a-constraints-crash.cpp index 637c55f0c879c9..6126a0509fa4a9 100644 --- a/clang/test/PCH/cxx2a-constraints-crash.cpp +++ b/clang/test/PCH/cxx2a-constraints-crash.cpp @@ -1,7 +1,5 @@ -// 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 +// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -emit-pch -o %t %s -verify +// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -include-pch %t %s -verify #ifndef HEADER #define HEADER @@ -27,3 +25,12 @@ int main() { } #endif + +namespace GH99036 { + +template <typename T> +concept C; // expected-error {{expected '='}} + +template <C U> void f(); // expected-error {{unknown type name 'C'}} + +} // namespace GH99036 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits