r213968 - Objective-C. Warn if protocol used in an @protocol

Fariborz Jahanian fjahanian at apple.com
Fri Jul 25 12:45:02 PDT 2014


Author: fjahanian
Date: Fri Jul 25 14:45:01 2014
New Revision: 213968

URL: http://llvm.org/viewvc/llvm-project?rev=213968&view=rev
Log:
Objective-C. Warn if protocol used in an @protocol
expression is a forward declaration as this results
in undefined behavior. rdar://17768630

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/SemaObjC/protocol-expr-1.m
    cfe/trunk/test/SemaObjC/protocol-expr-neg-1.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=213968&r1=213967&r2=213968&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jul 25 14:45:01 2014
@@ -428,6 +428,7 @@ def DeallocInCategory:DiagGroup<"dealloc
 def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
 def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
 def Protocol : DiagGroup<"protocol">;
+def AtProtocol : DiagGroup<"at-protocol">;
 def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
 def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
 def VariadicMacros : DiagGroup<"variadic-macros">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213968&r1=213967&r2=213968&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jul 25 14:45:01 2014
@@ -566,6 +566,8 @@ def err_protocol_has_circular_dependency
   "protocol has circular dependency">;
 def err_undeclared_protocol : Error<"cannot find protocol declaration for %0">;
 def warn_undef_protocolref : Warning<"cannot find protocol definition for %0">;
+def warn_atprotocol_protocol : Warning<
+  "@protocol is using a forward protocol declaration of %0">, InGroup<AtProtocol>;
 def warn_readonly_property : Warning<
   "attribute 'readonly' of property %0 restricts attribute "
   "'readwrite' of property inherited from %1">;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=213968&r1=213967&r2=213968&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 25 14:45:01 2014
@@ -6756,6 +6756,15 @@ Sema::CheckSingleAssignmentConstraints(Q
       return Incompatible;
   }
 
+  Expr *PRE = RHS.get()->IgnoreParenCasts();
+  if (ObjCProtocolExpr *OPE = dyn_cast<ObjCProtocolExpr>(PRE)) {
+    ObjCProtocolDecl *PDecl = OPE->getProtocol();
+    if (PDecl && !PDecl->hasDefinition()) {
+      Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl->getName();
+      Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
+    }
+  }
+  
   CastKind Kind = CK_Invalid;
   Sema::AssignConvertType result =
     CheckAssignmentConstraints(LHSType, RHS, Kind);

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=213968&r1=213967&r2=213968&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Jul 25 14:45:01 2014
@@ -1105,6 +1105,8 @@ ExprResult Sema::ParseObjCProtocolExpres
     Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
     return true;
   }
+  if (PDecl->hasDefinition())
+    PDecl = PDecl->getDefinition();
 
   QualType Ty = Context.getObjCProtoType();
   if (Ty.isNull())

Modified: cfe/trunk/test/SemaObjC/protocol-expr-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-expr-1.m?rev=213968&r1=213967&r2=213968&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-expr-1.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-expr-1.m Fri Jul 25 14:45:01 2014
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // expected-no-diagnostics
 
- at protocol fproto;
+ at protocol fproto @end
 
 @protocol p1 
 @end

Modified: cfe/trunk/test/SemaObjC/protocol-expr-neg-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-expr-neg-1.m?rev=213968&r1=213967&r2=213968&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-expr-neg-1.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-expr-neg-1.m Fri Jul 25 14:45:01 2014
@@ -2,7 +2,7 @@
 
 @class Protocol;
 
- at protocol fproto;
+ at protocol fproto; // expected-note {{'fproto' declared here}}
 
 @protocol p1 
 @end
@@ -12,8 +12,23 @@
 int main()
 {
 	Protocol *proto = @protocol(p1);
-        Protocol *fproto = @protocol(fproto);
+        Protocol *fproto = @protocol(fproto); // expected-warning {{@protocol is using a forward protocol declaration of fproto}}
 	Protocol *pp = @protocol(i); // expected-error {{cannot find protocol declaration for 'i'}}
 	Protocol *p1p = @protocol(cl); // expected-error {{cannot find protocol declaration for 'cl'}}
 }
 
+// rdar://17768630
+ at protocol SuperProtocol; // expected-note {{'SuperProtocol' declared here}}
+ at protocol TestProtocol; // expected-note {{'TestProtocol' declared here}}
+
+ at interface I
+- (int) conformsToProtocol : (Protocol *)protocl;
+ at end
+
+int doesConform(id foo) {
+  return [foo conformsToProtocol:@protocol(TestProtocol)]; // expected-warning {{@protocol is using a forward protocol declaration of TestProtocol}}
+}
+
+int doesConformSuper(id foo) {
+  return [foo conformsToProtocol:@protocol(SuperProtocol)]; // expected-warning {{@protocol is using a forward protocol declaration of SuperProtocol}}
+}





More information about the cfe-commits mailing list