[cfe-commits] r126162 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp test/SemaObjC/dist-object-modifiers.m
Fariborz Jahanian
fjahanian at apple.com
Mon Feb 21 15:49:15 PST 2011
Author: fjahanian
Date: Mon Feb 21 17:49:15 2011
New Revision: 126162
URL: http://llvm.org/viewvc/llvm-project?rev=126162&view=rev
Log:
Warn when type modifiers on objc method declarations in
protocols do not match with method implementation.
// rdar://7076235
Added:
cfe/trunk/test/SemaObjC/dist-object-modifiers.m
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=126162&r1=126161&r2=126162&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Feb 21 17:49:15 2011
@@ -351,12 +351,18 @@
def warn_conflicting_ret_types : Warning<
"conflicting return type in implementation of %0: %1 vs %2">;
+def warn_conflicting_ret_type_modifiers : Warning<
+ "conflicting distributed object modifiers on return type "
+ "in implementation of %0">;
def warn_non_covariant_ret_types : Warning<
"conflicting return type in implementation of %0: %1 vs %2">,
InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
def warn_conflicting_param_types : Warning<
"conflicting parameter types in implementation of %0: %1 vs %2">;
+def warn_conflicting_param_modifiers : Warning<
+ "conflicting distributed object modifiers on patameter type "
+ "in implementation of %0">;
def warn_non_contravariant_param_types : Warning<
"conflicting parameter types in implementation of %0: %1 vs %2">,
InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=126162&r1=126161&r2=126162&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Feb 21 17:49:15 2011
@@ -1523,7 +1523,8 @@
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
bool &IncompleteImpl, unsigned DiagID);
void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
- ObjCMethodDecl *IntfMethod);
+ ObjCMethodDecl *MethodDecl,
+ bool IsProtocolMethodDecl);
bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
ObjCInterfaceDecl *IDecl);
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=126162&r1=126161&r2=126162&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Feb 21 17:49:15 2011
@@ -856,9 +856,21 @@
static void CheckMethodOverrideReturn(Sema &S,
ObjCMethodDecl *MethodImpl,
- ObjCMethodDecl *MethodIface) {
+ ObjCMethodDecl *MethodDecl,
+ bool IsProtocolMethodDecl) {
+ if (IsProtocolMethodDecl &&
+ (MethodDecl->getObjCDeclQualifier() !=
+ MethodImpl->getObjCDeclQualifier())) {
+ S.Diag(MethodImpl->getLocation(),
+ diag::warn_conflicting_ret_type_modifiers)
+ << MethodImpl->getDeclName()
+ << getTypeRange(MethodImpl->getResultTypeSourceInfo());
+ S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
+ << getTypeRange(MethodDecl->getResultTypeSourceInfo());
+ }
+
if (S.Context.hasSameUnqualifiedType(MethodImpl->getResultType(),
- MethodIface->getResultType()))
+ MethodDecl->getResultType()))
return;
unsigned DiagID = diag::warn_conflicting_ret_types;
@@ -868,7 +880,7 @@
if (const ObjCObjectPointerType *ImplPtrTy =
MethodImpl->getResultType()->getAs<ObjCObjectPointerType>()) {
if (const ObjCObjectPointerType *IfacePtrTy =
- MethodIface->getResultType()->getAs<ObjCObjectPointerType>()) {
+ MethodDecl->getResultType()->getAs<ObjCObjectPointerType>()) {
// Allow non-matching return types as long as they don't violate
// the principle of substitutability. Specifically, we permit
// return types that are subclasses of the declared return type,
@@ -882,20 +894,33 @@
S.Diag(MethodImpl->getLocation(), DiagID)
<< MethodImpl->getDeclName()
- << MethodIface->getResultType()
+ << MethodDecl->getResultType()
<< MethodImpl->getResultType()
<< getTypeRange(MethodImpl->getResultTypeSourceInfo());
- S.Diag(MethodIface->getLocation(), diag::note_previous_definition)
- << getTypeRange(MethodIface->getResultTypeSourceInfo());
+ S.Diag(MethodDecl->getLocation(), diag::note_previous_definition)
+ << getTypeRange(MethodDecl->getResultTypeSourceInfo());
}
static void CheckMethodOverrideParam(Sema &S,
ObjCMethodDecl *MethodImpl,
- ObjCMethodDecl *MethodIface,
+ ObjCMethodDecl *MethodDecl,
ParmVarDecl *ImplVar,
- ParmVarDecl *IfaceVar) {
+ ParmVarDecl *IfaceVar,
+ bool IsProtocolMethodDecl) {
+ if (IsProtocolMethodDecl &&
+ (ImplVar->getObjCDeclQualifier() !=
+ IfaceVar->getObjCDeclQualifier())) {
+ S.Diag(ImplVar->getLocation(),
+ diag::warn_conflicting_param_modifiers)
+ << getTypeRange(ImplVar->getTypeSourceInfo())
+ << MethodImpl->getDeclName();
+ S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
+ << getTypeRange(IfaceVar->getTypeSourceInfo());
+ }
+
QualType ImplTy = ImplVar->getType();
QualType IfaceTy = IfaceVar->getType();
+
if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy))
return;
@@ -927,17 +952,20 @@
void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
- ObjCMethodDecl *IntfMethodDecl) {
- CheckMethodOverrideReturn(*this, ImpMethodDecl, IntfMethodDecl);
+ ObjCMethodDecl *MethodDecl,
+ bool IsProtocolMethodDecl) {
+ CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
+ IsProtocolMethodDecl);
for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
- IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
+ IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
IM != EM; ++IM, ++IF)
- CheckMethodOverrideParam(*this, ImpMethodDecl, IntfMethodDecl, *IM, *IF);
+ CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
+ IsProtocolMethodDecl);
- if (ImpMethodDecl->isVariadic() != IntfMethodDecl->isVariadic()) {
+ if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) {
Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_variadic);
- Diag(IntfMethodDecl->getLocation(), diag::note_previous_declaration);
+ Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
}
}
@@ -1061,13 +1089,14 @@
} else {
ObjCMethodDecl *ImpMethodDecl =
IMPDecl->getInstanceMethod((*I)->getSelector());
- ObjCMethodDecl *IntfMethodDecl =
+ ObjCMethodDecl *MethodDecl =
CDecl->getInstanceMethod((*I)->getSelector());
- assert(IntfMethodDecl &&
- "IntfMethodDecl is null in ImplMethodsVsClassMethods");
+ assert(MethodDecl &&
+ "MethodDecl is null in ImplMethodsVsClassMethods");
// ImpMethodDecl may be null as in a @dynamic property.
if (ImpMethodDecl)
- WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
+ isa<ObjCProtocolDecl>(CDecl));
}
}
@@ -1085,9 +1114,10 @@
} else {
ObjCMethodDecl *ImpMethodDecl =
IMPDecl->getClassMethod((*I)->getSelector());
- ObjCMethodDecl *IntfMethodDecl =
+ ObjCMethodDecl *MethodDecl =
CDecl->getClassMethod((*I)->getSelector());
- WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+ WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
+ isa<ObjCProtocolDecl>(CDecl));
}
}
Added: cfe/trunk/test/SemaObjC/dist-object-modifiers.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/dist-object-modifiers.m?rev=126162&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/dist-object-modifiers.m (added)
+++ cfe/trunk/test/SemaObjC/dist-object-modifiers.m Mon Feb 21 17:49:15 2011
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar://7076235
+
+ at protocol P
+- (bycopy id)serverPID; // expected-note {{previous declaration is here}}
+- (void)doStuff:(bycopy id)clientId; // expected-note {{previous declaration is here}}
+- (bycopy id)Ok;
++ (oneway id) stillMore : (byref id)Arg : (bycopy oneway id)Arg1; // expected-note 3 {{previous declaration is here}}
+ at end
+
+ at interface I <P>
+- (id)Ok;
+ at end
+
+ at implementation I
+- (id)serverPID { return 0; } // expected-warning {{conflicting distributed object modifiers on return type in implementation of 'serverPID'}}
+- (void)doStuff:(id)clientId { } // expected-warning {{conflicting distributed object modifiers on patameter type in implementation of 'doStuff:'}}
+- (bycopy id)Ok { return 0; }
++ (id) stillMore : (id)Arg : (bycopy id)Arg1 { return Arg; } // expected-warning {{conflicting distributed object modifiers on return type in implementation of 'stillMore::'}} \
+ // expected-warning 2{{conflicting distributed object modifiers on patameter type in implementation of 'stillMore::'}}
+ at end
More information about the cfe-commits
mailing list