From ba4fc23a3ad7629b353adc93bfab147b988683c2 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 11 Mar 2014 17:10:51 +0000 Subject: [PATCH] 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 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaDeclObjC.cpp | 23 +++++++++++++++++++++- test/Analysis/region-1.m | 2 +- test/SemaObjC/category-1.m | 3 ++- test/SemaObjC/class-def-test-1.m | 2 +- test/SemaObjC/class-proto-1.m | 14 ++++++++++++- 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c9bdcf12cb..4f93429a84 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2485,6 +2485,8 @@ def warn_objc_requires_super_protocol : Warning< InGroup>; 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< diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index e19432aea9..4de290b3eb 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -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); } } diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m index 9edb35b78b..6940c69dc1 100644 --- a/test/Analysis/region-1.m +++ b/test/Analysis/region-1.m @@ -25,7 +25,7 @@ typedef unsigned int NSUInteger; CK_UNRESTRICTED= 0, CK_READ_ONLY, CK_ADD_ONLY, CK_REMOVE_ONLY }; @protocol EcoClass - (NSArray *) ownedAttributes; @end @protocol EcoNamespace; -@protocol EcoType; +@protocol EcoType @end; @protocol EcoClassifier - (NSArray *) features; @end @protocol EcoComment; @protocol EcoElement - (NSArray *) ownedElements; diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index 3c2f7d0032..89ac550578 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -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) // expected-warning {{cannot find protocol definition for 'p1'}} expected-note {{previous definition is here}} @end diff --git a/test/SemaObjC/class-def-test-1.m b/test/SemaObjC/class-def-test-1.m index 7931cc3fdc..98a887ecab 100644 --- a/test/SemaObjC/class-def-test-1.m +++ b/test/SemaObjC/class-def-test-1.m @@ -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 @end // expected-warning {{cannot find protocol definition for 'SUPER'}} diff --git a/test/SemaObjC/class-proto-1.m b/test/SemaObjC/class-proto-1.m index 02c40aab65..51a899341e 100644 --- a/test/SemaObjC/class-proto-1.m +++ b/test/SemaObjC/class-proto-1.m @@ -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 @end + +// rdar://16111182 +@interface NSObject @end + +@protocol UndefinedParentProtocol; // expected-note {{protocol 'UndefinedParentProtocol' has no definition}} + +@protocol UndefinedProtocol +@end + +@interface SomeObject : NSObject // expected-warning {{cannot find protocol definition for 'UndefinedProtocol'}} +@end -- 2.40.0