mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 11:56:38 +00:00
[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.
This commit is contained in:
parent
e541aa5ff9
commit
ab51eccf88
@ -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();
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user