Skip to content

Commit fa2348c

Browse files
Merge pull request #755 from bcardosolopes/apple-stable-20200108-odr-objc-protocol-no-referenced-list-odrhash
[ODRHash] Check references protocols as part of MergeDefintionData
2 parents 8bd683f + 74b87a0 commit fa2348c

File tree

3 files changed

+85
-12
lines changed

3 files changed

+85
-12
lines changed

clang/lib/AST/ODRHash.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,6 @@ void ODRHash::AddObjCInterfaceDecl(const ObjCInterfaceDecl *IF) {
499499
AddBoolean(SuperClass);
500500
if (SuperClass)
501501
ID.AddInteger(SuperClass->getODRHash());
502-
ID.AddInteger(IF->getReferencedProtocols().size());
503-
for (auto *P : IF->protocols()) {
504-
unsigned ProtoHash = reinterpret_cast<ObjCProtocolDecl *>(P)->getODRHash();
505-
ID.AddInteger(ProtoHash);
506-
}
507502

508503
// Filter out sub-Decls which will not be processed in order to get an
509504
// accurate count of Decl's.
@@ -524,13 +519,6 @@ void ODRHash::AddObjCProtocolDecl(const ObjCProtocolDecl *P) {
524519
for (auto *M : P->methods())
525520
reinterpret_cast<ObjCMethodDecl *>(M)->getODRHash();
526521

527-
// Store the hash of each referenced protocol.
528-
ID.AddInteger(P->getReferencedProtocols().size());
529-
for (auto *RefP : P->protocols()) {
530-
unsigned RefHash = reinterpret_cast<ObjCProtocolDecl *>(RefP)->getODRHash();
531-
ID.AddInteger(RefHash);
532-
}
533-
534522
// Filter out sub-Decls which will not be processed in order to get an
535523
// accurate count of Decl's.
536524
llvm::SmallVector<const Decl *, 16> Decls;

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,30 @@ void ASTDeclReader::ReadObjCDefinitionData(
11521152
Reader.getContext());
11531153
}
11541154

1155+
static bool MergeCheckProtocolList(const ObjCProtocolList &FirstProtos,
1156+
const ObjCProtocolList &SecondProtos) {
1157+
if (FirstProtos.size() != SecondProtos.size())
1158+
return true;
1159+
1160+
for (unsigned I = 0, E = FirstProtos.size(); I != E; ++I) {
1161+
auto *FirstParam = FirstProtos[I];
1162+
auto *SecondParam = SecondProtos[I];
1163+
DeclarationName FirstParamName = FirstParam->getDeclName();
1164+
DeclarationName SecondParamName = SecondParam->getDeclName();
1165+
1166+
// If parameters match name but do not both have a definition, we
1167+
// can't disambiguate it during ODR diagnostic time, skip.
1168+
if (FirstParamName == SecondParamName &&
1169+
(FirstParam->hasDefinition() != SecondParam->hasDefinition()))
1170+
return false;
1171+
1172+
if (FirstParamName != SecondParamName)
1173+
return true;
1174+
}
1175+
1176+
return false;
1177+
}
1178+
11551179
void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D,
11561180
struct ObjCInterfaceDecl::DefinitionData &&NewDD) {
11571181
bool DetectedOdrViolation = false;
@@ -1163,6 +1187,10 @@ void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D,
11631187
NewDD.CategoryList)
11641188
return;
11651189

1190+
auto &FirstProtos = D->getReferencedProtocols();
1191+
auto &SecondProtos = NewDD.ReferencedProtocols;
1192+
if (MergeCheckProtocolList(FirstProtos, SecondProtos))
1193+
DetectedOdrViolation = true;
11661194
if (D->getODRHash() != NewDD.ODRHash)
11671195
DetectedOdrViolation = true;
11681196

@@ -1239,6 +1267,10 @@ void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D,
12391267
bool DetectedOdrViolation = false;
12401268
auto &DD = D->data();
12411269

1270+
auto &FirstProtos = D->getReferencedProtocols();
1271+
auto &SecondProtos = NewDD.ReferencedProtocols;
1272+
if (MergeCheckProtocolList(FirstProtos, SecondProtos))
1273+
DetectedOdrViolation = true;
12421274
if (D->getODRHash() != NewDD.ODRHash)
12431275
DetectedOdrViolation = true;
12441276

clang/test/Modules/odr_hash.m

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ @protocol P1
4646
@protocol P2
4747
@end
4848

49+
@protocol UP1;
50+
@protocol UP2;
51+
@protocol UP3;
52+
4953
@interface I1
5054
@end
5155

@@ -623,6 +627,55 @@ @interface IMW5 <MW5> // No diagnostics: @required is the default.
623627
@end
624628
#endif
625629

630+
#if defined(FIRST)
631+
@protocol PP1 <UP1>
632+
@end
633+
#elif defined(SECOND)
634+
@protocol UP1
635+
@end
636+
@protocol PP11 <UP1>
637+
@end
638+
#else
639+
@interface II0 <PP1>
640+
@end
641+
II0 *ii0;
642+
#endif
643+
644+
#if defined(FIRST)
645+
@protocol PP2 <UP2>
646+
@end
647+
#elif defined(SECOND)
648+
@protocol PP2 <UP2>
649+
@end
650+
#else
651+
#endif
652+
653+
#if defined(FIRST)
654+
@protocol PP3 <UP2>
655+
@end
656+
#elif defined(SECOND)
657+
@protocol PP3 <UP3>
658+
@end
659+
#else
660+
@protocol PP4 <PP3>
661+
@end
662+
// [email protected]:* {{'PP3' has different definitions in different modules; first difference is definition in module 'FirstModule' found with 1st protocol named 'UP2'}}
663+
// [email protected]:* {{but in 'SecondModule' found with 1st protocol named 'UP3'}}
664+
#endif
665+
666+
#if defined(FIRST)
667+
@interface II1 <UP3>
668+
@end
669+
// [email protected]:* {{cannot find protocol definition for 'UP3'}}
670+
// [email protected]:* {{protocol 'UP3' has no definition}}
671+
#elif defined(SECOND)
672+
@protocol UP3
673+
@end
674+
@interface II1 <UP3>
675+
@end
676+
#else
677+
#endif
678+
626679
// Keep macros contained to one file.
627680
#ifdef FIRST
628681
#undef FIRST

0 commit comments

Comments
 (0)