diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 232003f256ee7..be1d8f924e680 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1540,22 +1540,15 @@ void Sema::DiagnoseUnsatisfiedConstraint( const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints( ConstrainedDeclOrNestedRequirement ConstrainedDeclOrNestedReq, ArrayRef AssociatedConstraints) { - // In case the ConstrainedDecl comes from modules, it is necessary to use - // the canonical decl to avoid different atomic constraints with the 'same' - // declarations. - if (!ConstrainedDeclOrNestedReq) return NormalizedConstraint::fromAssociatedConstraints( *this, nullptr, AssociatedConstraints); const NamedDecl *ND = ConstrainedDeclOrNestedReq.dyn_cast(); - if (ND) - ND = cast(ND->getCanonicalDecl()); - auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq); if (CacheEntry == NormalizationCache.end()) { - auto Normalized = NormalizedConstraint::fromAssociatedConstraints( + auto *Normalized = NormalizedConstraint::fromAssociatedConstraints( *this, ND, AssociatedConstraints); CacheEntry = NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized) @@ -1795,10 +1788,12 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr( // constraint. If any such substitution results in an invalid type or // expression, the program is ill-formed; no diagnostic is required. // [...] - ConceptDecl *CD = CSE->getNamedConcept(); + + // Use canonical declarations to merge ConceptDecls across + // different modules. + ConceptDecl *CD = CSE->getNamedConcept()->getCanonicalDecl(); SubNF = NormalizedConstraint::fromAssociatedConstraints( - S, CSE->getNamedConcept(), - AssociatedConstraint(CD->getConstraintExpr(), SubstIndex)); + S, CD, AssociatedConstraint(CD->getConstraintExpr(), SubstIndex)); if (!SubNF) return nullptr; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 01c838b955755..126d3246e38b7 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -802,15 +802,20 @@ readConstraintSatisfaction(ASTRecordReader &Record) { if (!Satisfaction.IsSatisfied) { unsigned NumDetailRecords = Record.readInt(); for (unsigned i = 0; i != NumDetailRecords; ++i) { - if (/* IsDiagnostic */Record.readInt()) { + auto Kind = Record.readInt(); + if (Kind == 0) { SourceLocation DiagLocation = Record.readSourceLocation(); StringRef DiagMessage = C.backupStr(Record.readString()); Satisfaction.Details.emplace_back( new (C) ConstraintSatisfaction::SubstitutionDiagnostic( DiagLocation, DiagMessage)); - } else + } else if (Kind == 1) { Satisfaction.Details.emplace_back(Record.readExpr()); + } else { + assert(Kind == 2); + Satisfaction.Details.emplace_back(Record.readConceptReference()); + } } } return Satisfaction; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index bf19cbab65b8f..e0f14fecc6638 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -475,14 +475,20 @@ addConstraintSatisfaction(ASTRecordWriter &Record, if (!Satisfaction.IsSatisfied) { Record.push_back(Satisfaction.NumRecords); for (const auto &DetailRecord : Satisfaction) { - auto *E = dyn_cast(DetailRecord); - Record.push_back(/* IsDiagnostic */ E == nullptr); - if (E) - Record.AddStmt(const_cast(E)); - else { - auto *Diag = cast *>(DetailRecord); + if (auto *Diag = + dyn_cast *>(DetailRecord)) { + Record.push_back(/*Kind=*/0); Record.AddSourceLocation(Diag->first); Record.AddString(Diag->second); + continue; + } + if (auto *E = dyn_cast(DetailRecord)) { + Record.push_back(/*Kind=*/1); + Record.AddStmt(const_cast(E)); + } else { + Record.push_back(/*Kind=*/2); + auto *CR = cast(DetailRecord); + Record.AddConceptReference(CR); } } }