def OverlengthStrings : DiagGroup<"overlength-strings">;
def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
def PrivateExtern : DiagGroup<"private-extern">;
+def SelTypeCast : DiagGroup<"cast-of-sel-type">;
def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
VolatileRegisterVar,
ObjCMissingSuperCalls,
OverloadedVirtual,
- PrivateExtern
+ PrivateExtern,
+ SelTypeCast
]>;
// Thread Safety warnings
"cast to union type from type %0 not present in union">;
def err_cast_pointer_from_non_pointer_int : Error<
"operand of type %0 cannot be cast to a pointer type">;
+def warn_cast_pointer_from_sel : Warning<
+ "cast of type %0 to %1 is deprecated; use sel_getName instead">,
+ InGroup<SelTypeCast>, DefaultIgnore;
def err_cast_pointer_to_non_pointer_int : Error<
"pointer cannot be cast to type %0">;
def err_typecheck_expect_scalar_operand : Error<
Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
}
+static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr,
+ QualType DestType) {
+ QualType SrcType = SrcExpr.get()->getType();
+ if (const PointerType *SrcPtrTy = SrcType->getAs<PointerType>())
+ if (SrcPtrTy->isObjCSelType()) {
+ QualType DT = DestType;
+ if (isa<PointerType>(DestType))
+ DT = DestType->getPointeeType();
+ if (!DT.getUnqualifiedType()->isVoidType())
+ Self.Diag(SrcExpr.get()->getExprLoc(),
+ diag::warn_cast_pointer_from_sel)
+ << SrcType << DestType << SrcExpr.get()->getSourceRange();
+ }
+}
+
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
if (CStyle && DestType->isObjCObjectPointerType()) {
return TC_Success;
}
-
+ if (CStyle)
+ DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
+
// Not casting away constness, so the only remaining check is for compatible
// pointer categories.
return;
}
}
+ DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
Kind = Self.PrepareScalarCast(SrcExpr, DestType);
if (SrcExpr.isInvalid())
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -verify -Wcast-of-sel-type -Wno-unused-value %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wcast-of-sel-type -Wno-unused-value %s
+// rdar://12107381
+
+SEL s;
+
+SEL sel_registerName(const char *);
+
+int main() {
+(char *)s; // expected-warning {{cast of type 'SEL' to 'char *' is deprecated; use sel_getName instead}}
+(void *)s; // ok
+(const char *)sel_registerName("foo"); // expected-warning {{cast of type 'SEL' to 'const char *' is deprecated; use sel_getName instead}}
+
+(const void *)sel_registerName("foo"); // ok
+
+(void) s; // ok
+
+(void *const)s; // ok
+
+(const void *const)s; // ok
+}