@@ -6973,31 +6973,40 @@ static void handleVTablePointerAuthentication(Sema &S, Decl *D,
69736973 CustomDiscriminationValue));
69746974}
69756975
6976- static bool modularFormatIsSame (const ModularFormatAttr *Existing,
6977- IdentifierInfo *ModularImplFn,
6978- StringRef ImplName,
6979- ArrayRef<StringRef> Aspects) {
6980- if (Existing->getModularImplFn () != ModularImplFn)
6981- return false ;
6982- if (Existing->getImplName () != ImplName)
6983- return false ;
6984- if (Existing->aspects_size () != Aspects.size ())
6985- return false ;
6986- unsigned I = 0 ;
6987- for (const auto &ExistingAspect : Existing->aspects ()) {
6988- if (ExistingAspect != Aspects[I++])
6989- return false ;
6976+ static bool modularFormatAttrsEquiv (const ModularFormatAttr *Existing,
6977+ IdentifierInfo *ModularImplFn,
6978+ StringRef ImplName,
6979+ ArrayRef<StringRef> Aspects) {
6980+ return Existing->getModularImplFn () == ModularImplFn &&
6981+ Existing->getImplName () == ImplName &&
6982+ Existing->aspects_size () == Aspects.size () &&
6983+ llvm::equal (Existing->aspects (), Aspects);
6984+ }
6985+
6986+ ModularFormatAttr *
6987+ Sema::mergeModularFormatAttr (Decl *D, const AttributeCommonInfo &CI,
6988+ IdentifierInfo *ModularImplFn, StringRef ImplName,
6989+ MutableArrayRef<StringRef> Aspects) {
6990+ if (const auto *Existing = D->getAttr <ModularFormatAttr>()) {
6991+ if (!modularFormatAttrsEquiv (Existing, ModularImplFn, ImplName, Aspects)) {
6992+ Diag (Existing->getLocation (), diag::err_duplicate_attribute) << *Existing;
6993+ Diag (CI.getLoc (), diag::note_conflicting_attribute);
6994+ }
6995+ // Drop the existing attribute on the declaration in favor of the newly
6996+ // inherited one.
6997+ D->dropAttr <ModularFormatAttr>();
69906998 }
6991- return true ;
6999+ return ::new (Context) ModularFormatAttr (Context, CI, ModularImplFn, ImplName,
7000+ Aspects.data (), Aspects.size ());
69927001}
69937002
69947003static void handleModularFormat (Sema &S, Decl *D, const ParsedAttr &AL) {
7004+ bool Valid = true ;
69957005 StringRef ImplName;
69967006 if (!S.checkStringLiteralArgumentAttr (AL, 1 , ImplName))
6997- return ;
7007+ Valid = false ;
69987008 SmallVector<StringRef> Aspects;
69997009 llvm::DenseSet<StringRef> SeenAspects;
7000- bool HasDuplicate = false ;
70017010 for (unsigned I = 2 , E = AL.getNumArgs (); I != E; ++I) {
70027011 StringRef Aspect;
70037012 if (!S.checkStringLiteralArgumentAttr (AL, I, Aspect))
@@ -7006,27 +7015,26 @@ static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
70067015 S.Diag (AL.getArgAsExpr (I)->getExprLoc (),
70077016 diag::err_modular_format_duplicate_aspect)
70087017 << Aspect;
7009- HasDuplicate = true ;
7018+ Valid = false ;
70107019 continue ;
70117020 }
70127021 Aspects.push_back (Aspect);
70137022 }
7023+ if (!Valid)
7024+ return ;
70147025
70157026 // Store aspects sorted.
70167027 llvm::sort (Aspects);
7017-
70187028 IdentifierInfo *ModularImplFn = AL.getArgAsIdent (0 )->getIdentifierInfo ();
70197029
70207030 if (const auto *Existing = D->getAttr <ModularFormatAttr>()) {
7021- if (!modularFormatIsSame (Existing, ModularImplFn, ImplName, Aspects)) {
7022- S.Diag (AL.getLoc (), diag::warn_duplicate_attribute ) << AL ;
7023- S.Diag (Existing->getLocation (), diag::note_conflicting_attribute);
7031+ if (!modularFormatAttrsEquiv (Existing, ModularImplFn, ImplName, Aspects)) {
7032+ S.Diag (AL.getLoc (), diag::err_duplicate_attribute ) << *Existing ;
7033+ S.Diag (Existing->getLoc (), diag::note_conflicting_attribute);
70247034 }
7025- D->dropAttr <ModularFormatAttr>();
7026- }
7027-
7028- if (HasDuplicate)
7035+ // Ignore the later declaration in favor of the earlier one.
70297036 return ;
7037+ }
70307038
70317039 D->addAttr (::new (S.Context ) ModularFormatAttr (
70327040 S.Context , AL, ModularImplFn, ImplName, Aspects.data (), Aspects.size ()));
0 commit comments