https://github.com/falbrechtskirchinger updated 
https://github.com/llvm/llvm-project/pull/113182

>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

Reply via email to