Objective-C. Diagose use of undefined protocols

when a class adopts a protocol that inherits from 
undefined protocols. // rdar://16111182


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203586 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2014-03-11 17:10:51 +00:00
parent 22cc9b0c3b
commit ba4fc23a3a
6 changed files with 41 additions and 5 deletions

View File

@ -2485,6 +2485,8 @@ def warn_objc_requires_super_protocol : Warning<
InGroup<DiagGroup<"requires-super-attribute">>;
def note_protocol_decl : Note<
"protocol is declared here">;
def note_protocol_decl_undefined : Note<
"protocol %0 has no definition">;
// objc_designated_initializer attribute diagnostics.
def warn_objc_designated_init_missing_super_call : Warning<

View File

@ -760,6 +760,22 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
return ActOnObjCContainerStartDefinition(PDecl);
}
static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl,
ObjCProtocolDecl *&UndefinedProtocol) {
if (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()) {
UndefinedProtocol = PDecl;
return true;
}
for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
E = PDecl->protocol_end(); PI != E; ++PI)
if (NestedProtocolHasNoDefinition((*PI), UndefinedProtocol)) {
UndefinedProtocol = (*PI);
return true;
}
return false;
}
/// FindProtocolDeclaration - This routine looks up protocols and
/// issues an error if they are not declared. It returns list of
/// protocol declarations in its 'Protocols' argument.
@ -795,10 +811,15 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
// If this is a forward declaration and we are supposed to warn in this
// case, do it.
// FIXME: Recover nicely in the hidden case.
ObjCProtocolDecl *UndefinedProtocol;
if (WarnOnDeclarations &&
(!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()))
NestedProtocolHasNoDefinition(PDecl, UndefinedProtocol)) {
Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
<< ProtocolId[i].first;
Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)
<< UndefinedProtocol;
}
Protocols.push_back(PDecl);
}
}

View File

@ -25,7 +25,7 @@ typedef unsigned int NSUInteger;
CK_UNRESTRICTED= 0, CK_READ_ONLY, CK_ADD_ONLY, CK_REMOVE_ONLY };
@protocol EcoClass <EcoBehavioredClassifier> - (NSArray *) ownedAttributes;
@end @protocol EcoNamespace;
@protocol EcoType;
@protocol EcoType @end;
@protocol EcoClassifier <EcoNamespace,EcoType> - (NSArray *) features;
@end @protocol EcoComment;
@protocol EcoElement <NSObject> - (NSArray *) ownedElements;

View File

@ -2,7 +2,8 @@
@interface MyClass1 @end
@protocol p1,p2,p3;
@protocol p1,p2,p3; // expected-note {{protocol 'p1' has no definition}} \
// expected-note {{protocol 'p2' has no definition}}
@interface MyClass1 (Category1) <p1> // expected-warning {{cannot find protocol definition for 'p1'}} expected-note {{previous definition is here}}
@end

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
@protocol SUPER;
@protocol SUPER; // expected-note {{protocol 'SUPER' has no definition}}
@interface SUPER <SUPER> @end // expected-warning {{cannot find protocol definition for 'SUPER'}}

View File

@ -2,7 +2,8 @@
@interface INTF1 @end
@protocol p1,p2,p3;
@protocol p1,p2,p3; // expected-note {{protocol 'p2' has no definition}} \
// expected-note {{protocol 'p3' has no definition}}
@protocol p1;
@ -34,3 +35,14 @@
@interface I4 : U2 <p1,p2>
@end
// rdar://16111182
@interface NSObject @end
@protocol UndefinedParentProtocol; // expected-note {{protocol 'UndefinedParentProtocol' has no definition}}
@protocol UndefinedProtocol <UndefinedParentProtocol>
@end
@interface SomeObject : NSObject <UndefinedProtocol> // expected-warning {{cannot find protocol definition for 'UndefinedProtocol'}}
@end