@@ -176,7 +176,13 @@ void DylibVerifier::addSymbol(const Record *R, SymbolContext &SymCtx,
176
176
177
177
bool DylibVerifier::shouldIgnoreObsolete (const Record *R, SymbolContext &SymCtx,
178
178
const Record *DR) {
179
- return SymCtx.FA ->Avail .isObsoleted ();
179
+ if (!SymCtx.FA ->Avail .isObsoleted ())
180
+ return false ;
181
+
182
+ if (Zippered)
183
+ DeferredZipperedSymbols[SymCtx.SymbolName ].emplace_back (ZipperedDeclSource{
184
+ SymCtx.FA , &Ctx.Diag ->getSourceManager (), Ctx.Target });
185
+ return true ;
180
186
}
181
187
182
188
bool DylibVerifier::shouldIgnoreReexport (const Record *R,
@@ -195,6 +201,28 @@ bool DylibVerifier::shouldIgnoreReexport(const Record *R,
195
201
return false ;
196
202
}
197
203
204
+ bool DylibVerifier::shouldIgnoreInternalZipperedSymbol (
205
+ const Record *R, const SymbolContext &SymCtx) const {
206
+ if (!Zippered)
207
+ return false ;
208
+
209
+ return Exports->findSymbol (SymCtx.Kind , SymCtx.SymbolName ,
210
+ SymCtx.ObjCIFKind ) != nullptr ;
211
+ }
212
+
213
+ bool DylibVerifier::shouldIgnoreZipperedAvailability (const Record *R,
214
+ SymbolContext &SymCtx) {
215
+ if (!(Zippered && SymCtx.FA ->Avail .isUnavailable ()))
216
+ return false ;
217
+
218
+ // Collect source location incase there is an exported symbol to diagnose
219
+ // during `verifyRemainingSymbols`.
220
+ DeferredZipperedSymbols[SymCtx.SymbolName ].emplace_back (
221
+ ZipperedDeclSource{SymCtx.FA , SourceManagers.back ().get (), Ctx.Target });
222
+
223
+ return true ;
224
+ }
225
+
198
226
bool DylibVerifier::compareObjCInterfaceSymbols (const Record *R,
199
227
SymbolContext &SymCtx,
200
228
const ObjCInterfaceRecord *DR) {
@@ -294,6 +322,9 @@ DylibVerifier::Result DylibVerifier::compareVisibility(const Record *R,
294
322
if (shouldIgnorePrivateExternAttr (SymCtx.FA ->D ))
295
323
return Result::Ignore;
296
324
325
+ if (shouldIgnoreInternalZipperedSymbol (R, SymCtx))
326
+ return Result::Ignore;
327
+
297
328
unsigned ID;
298
329
Result Outcome;
299
330
if (Mode == VerificationMode::ErrorsAndWarnings) {
@@ -321,6 +352,9 @@ DylibVerifier::Result DylibVerifier::compareAvailability(const Record *R,
321
352
if (!SymCtx.FA ->Avail .isUnavailable ())
322
353
return Result::Valid;
323
354
355
+ if (shouldIgnoreZipperedAvailability (R, SymCtx))
356
+ return Result::Ignore;
357
+
324
358
const bool IsDeclAvailable = SymCtx.FA ->Avail .isUnavailable ();
325
359
326
360
switch (Mode) {
@@ -588,13 +622,58 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) {
588
622
}
589
623
}
590
624
625
+ const bool IsLinkerSymbol = SymbolName.starts_with (" $ld$" );
626
+
627
+ if (R.isVerified ()) {
628
+ // Check for unavailable symbols.
629
+ // This should only occur in the zippered case where we ignored
630
+ // availability until all headers have been parsed.
631
+ auto It = DeferredZipperedSymbols.find (SymCtx.SymbolName );
632
+ if (It == DeferredZipperedSymbols.end ()) {
633
+ updateState (Result::Valid);
634
+ return ;
635
+ }
636
+
637
+ ZipperedDeclSources Locs;
638
+ for (const ZipperedDeclSource &ZSource : It->second ) {
639
+ if (ZSource.FA ->Avail .isObsoleted ()) {
640
+ updateState (Result::Ignore);
641
+ return ;
642
+ }
643
+ if (ZSource.T .Arch != Ctx.Target .Arch )
644
+ continue ;
645
+ Locs.emplace_back (ZSource);
646
+ }
647
+ assert (Locs.size () == 2 && " Expected two decls for zippered symbol" );
648
+
649
+ // Print violating declarations per platform.
650
+ for (const ZipperedDeclSource &ZSource : Locs) {
651
+ unsigned DiagID = 0 ;
652
+ if (Mode == VerificationMode::Pedantic || IsLinkerSymbol) {
653
+ updateState (Result::Invalid);
654
+ DiagID = diag::err_header_availability_mismatch;
655
+ } else if (Mode == VerificationMode::ErrorsAndWarnings) {
656
+ updateState (Result::Ignore);
657
+ DiagID = diag::warn_header_availability_mismatch;
658
+ } else {
659
+ updateState (Result::Ignore);
660
+ return ;
661
+ }
662
+ // Bypass emitDiag banner and print the target everytime.
663
+ Ctx.Diag ->setSourceManager (ZSource.SrcMgr );
664
+ Ctx.Diag ->Report (diag::warn_target) << getTargetTripleName (ZSource.T );
665
+ Ctx.Diag ->Report (ZSource.FA ->Loc , DiagID)
666
+ << getAnnotatedName (&R, SymCtx) << ZSource.FA ->Avail .isUnavailable ()
667
+ << ZSource.FA ->Avail .isUnavailable ();
668
+ }
669
+ return ;
670
+ }
671
+
591
672
if (shouldIgnoreCpp (SymbolName, R.isWeakDefined ())) {
592
673
updateState (Result::Valid);
593
674
return ;
594
675
}
595
676
596
- const bool IsLinkerSymbol = SymbolName.starts_with (" $ld$" );
597
-
598
677
// All checks at this point classify as some kind of violation.
599
678
// The different verification modes dictate whether they are reported to the
600
679
// user.
@@ -647,8 +726,6 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) {
647
726
}
648
727
649
728
void DylibVerifier::visitGlobal (const GlobalRecord &R) {
650
- if (R.isVerified ())
651
- return ;
652
729
SymbolContext SymCtx;
653
730
SimpleSymbol Sym = parseSymbol (R.getName ());
654
731
SymCtx.SymbolName = Sym.Name ;
@@ -658,8 +735,6 @@ void DylibVerifier::visitGlobal(const GlobalRecord &R) {
658
735
659
736
void DylibVerifier::visitObjCIVar (const ObjCIVarRecord &R,
660
737
const StringRef Super) {
661
- if (R.isVerified ())
662
- return ;
663
738
SymbolContext SymCtx;
664
739
SymCtx.SymbolName = ObjCIVarRecord::createScopedName (Super, R.getName ());
665
740
SymCtx.Kind = EncodeKind::ObjectiveCInstanceVariable;
@@ -679,8 +754,6 @@ void DylibVerifier::accumulateSrcLocForDylibSymbols() {
679
754
}
680
755
681
756
void DylibVerifier::visitObjCInterface (const ObjCInterfaceRecord &R) {
682
- if (R.isVerified ())
683
- return ;
684
757
SymbolContext SymCtx;
685
758
SymCtx.SymbolName = R.getName ();
686
759
SymCtx.ObjCIFKind = assignObjCIFSymbolKind (&R);
@@ -713,9 +786,12 @@ DylibVerifier::Result DylibVerifier::verifyRemainingSymbols() {
713
786
714
787
DWARFContext DWARFInfo;
715
788
DWARFCtx = &DWARFInfo;
716
- Ctx.DiscoveredFirstError = false ;
717
- Ctx.PrintArch = true ;
789
+ Ctx.Target = Target (Architecture::AK_unknown, PlatformType::PLATFORM_UNKNOWN);
718
790
for (std::shared_ptr<RecordsSlice> Slice : Dylib) {
791
+ if (Ctx.Target .Arch == Slice->getTarget ().Arch )
792
+ continue ;
793
+ Ctx.DiscoveredFirstError = false ;
794
+ Ctx.PrintArch = true ;
719
795
Ctx.Target = Slice->getTarget ();
720
796
Ctx.DylibSlice = Slice.get ();
721
797
Slice->visit (*this );
0 commit comments