https://github.com/falbrechtskirchinger created https://github.com/llvm/llvm-project/pull/110496
Note: This patch is based on the assumption, that an assertion causing a crash in clangd, is incorrect. Alternatively, the true error may lie elsewhere, possibly in ´Sema::BuildTypeConstraint`/`Sema::AttachTypeConstraint`. Someone with more experience is needed to make that call. Commit message follows. <hr /> The ASTWriter currently assumes template type constraints to be initialized ((bool)getTypeConstraint() == hasTypeConstraint()). The attached test case presents a scenario where that is not the case. This patch removes the assumption and adds another boolean to the serialization, to explicitly encode whether the type constraint has been initialized. Fixes #99036. Fixes #109354. >From 296cc1b1389cc1a7aff4f5a84a48b6db4fe9e59a Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger <falbrechtskirchin...@gmail.com> Date: Mon, 30 Sep 2024 12:58:15 +0200 Subject: [PATCH] [clangd] [AST] Handle uninitialized type constraints The ASTWriter currently assumes template type constraints to be initialized ((bool)getTypeConstraint() == hasTypeConstraint()). The attached test case presents a scenario where that is not the case. This patch removes the assumption and adds another boolean to the serialization, to explicitly encode whether the type constraint has been initialized. Fixes #99036. Fixes #109354. --- clang-tools-extra/clangd/test/GH99036.test | 29 ++++++++++++++++++++++ clang/lib/Serialization/ASTReaderDecl.cpp | 2 +- clang/lib/Serialization/ASTWriterDecl.cpp | 5 ++-- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/clangd/test/GH99036.test diff --git a/clang-tools-extra/clangd/test/GH99036.test b/clang-tools-extra/clangd/test/GH99036.test new file mode 100644 index 00000000000000..64ebe4c75a999d --- /dev/null +++ b/clang-tools-extra/clangd/test/GH99036.test @@ -0,0 +1,29 @@ +# RUN: rm -rf %t +# RUN: mkdir -p %t +# RUN: split-file %s %t +# +# RUN: not clangd --check=%t/main.cpp 2>&1 | FileCheck -strict-whitespace %s +# +# CHECK: Loaded compilation database +# CHECK-NEXT: Compile command inferred from main.cpp is: +# CHECK: Indexing headers... +# CHECK-NEXT: [unknown_typename] Line 1: in included file: unknown type name '_Up' +# CHECK: All checks completed, 1 errors + +#--- header.h +template<_Up> +concept __decayed_same_as; +template<__decayed_same_as> +partial_ordering operator0 + +#--- main.cpp +#include "header.h" + +#--- compile_commands.json +[ + { + "directory": "/", + "command": "c++ -std=c++20", + "file": "main.cpp" + } +] diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7cead2728ca938..90783963934bb0 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2674,7 +2674,7 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); - if (D->hasTypeConstraint()) { + if (Record.readBool() && 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 b71684569609ac..1c9898c042cd4b 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1899,7 +1899,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { Record.push_back(D->wasDeclaredWithTypename()); const TypeConstraint *TC = D->getTypeConstraint(); - assert((bool)TC == D->hasTypeConstraint()); + Record.push_back(TC != nullptr); // reflects TypeConstraintInitialized if (TC) { auto *CR = TC->getConceptReference(); Record.push_back(CR != nullptr); @@ -1917,7 +1917,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() && @@ -2580,6 +2580,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)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits