forked from OSchip/llvm-project
Split off casts to void* for -Wint-to-pointer-cast to subgroup -Wint-to-void-pointer-cast.
This change is motivated from user feedback that some APIs use void* as an opaque "context" object that may not really be a pointer. Such users want an ability to turn off the warning for casts to void* while preserving the warning for other cases. Implements <rdar://problem/14016721>. llvm-svn: 182884
This commit is contained in:
parent
00e08db393
commit
e3dc7f74be
|
@ -416,7 +416,9 @@ def Format2 : DiagGroup<"format=2",
|
|||
|
||||
def TypeSafety : DiagGroup<"type-safety">;
|
||||
|
||||
def IntToPointerCast : DiagGroup<"int-to-pointer-cast">;
|
||||
def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
|
||||
def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
|
||||
[IntToVoidPointerCast]>;
|
||||
|
||||
def Extra : DiagGroup<"extra", [
|
||||
MissingFieldInitializers,
|
||||
|
|
|
@ -2222,9 +2222,17 @@ def warn_cast_align : Warning<
|
|||
"cast from %0 to %1 increases required alignment from %2 to %3">,
|
||||
InGroup<CastAlign>, DefaultIgnore;
|
||||
|
||||
// Separate between casts to void* and non-void* pointers.
|
||||
// Some APIs use (abuse) void* for something like a user context,
|
||||
// and often that value is an integer even if it isn't a pointer itself.
|
||||
// Having a separate warning flag allows users to control the warning
|
||||
// for their workflow.
|
||||
def warn_int_to_pointer_cast : Warning<
|
||||
"cast to %1 from smaller integer type %0">,
|
||||
InGroup<IntToPointerCast>;
|
||||
def warn_int_to_void_pointer_cast : Warning<
|
||||
"cast to %1 from smaller integer type %0">,
|
||||
InGroup<IntToVoidPointerCast>;
|
||||
|
||||
def warn_attribute_ignored_for_field_of_type : Warning<
|
||||
"%0 attribute ignored for field of type %1">,
|
||||
|
|
|
@ -1614,8 +1614,18 @@ static void checkIntToPointerCast(bool CStyle, SourceLocation Loc,
|
|||
&& !SrcType->isBooleanType()
|
||||
&& !SrcType->isEnumeralType()
|
||||
&& !SrcExpr->isIntegerConstantExpr(Self.Context)
|
||||
&& Self.Context.getTypeSize(DestType) > Self.Context.getTypeSize(SrcType))
|
||||
Self.Diag(Loc, diag::warn_int_to_pointer_cast) << SrcType << DestType;
|
||||
&& Self.Context.getTypeSize(DestType) >
|
||||
Self.Context.getTypeSize(SrcType)) {
|
||||
// Separate between casts to void* and non-void* pointers.
|
||||
// Some APIs use (abuse) void* for something like a user context,
|
||||
// and often that value is an integer even if it isn't a pointer itself.
|
||||
// Having a separate warning flag allows users to control the warning
|
||||
// for their workflow.
|
||||
unsigned Diag = DestType->isVoidPointerType() ?
|
||||
diag::warn_int_to_void_pointer_cast
|
||||
: diag::warn_int_to_pointer_cast;
|
||||
Self.Diag(Loc, Diag) << SrcType << DestType;
|
||||
}
|
||||
}
|
||||
|
||||
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
|
||||
|
|
|
@ -54,6 +54,14 @@ void testInt(Int v) {
|
|||
(void) (CDouble) v;
|
||||
(void) (VoidPtr) v; // expected-warning{{cast to 'VoidPtr' (aka 'void *') from smaller integer type 'Int' (aka 'int')}}
|
||||
(void) (CharPtr) v; // expected-warning{{cast to 'CharPtr' (aka 'char *') from smaller integer type 'Int' (aka 'int')}}
|
||||
|
||||
// Test that casts to void* can be controlled separately
|
||||
// from other -Wint-to-pointer-cast warnings.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
|
||||
(void) (VoidPtr) v; // no-warning
|
||||
(void) (CharPtr) v; // expected-warning{{cast to 'CharPtr' (aka 'char *') from smaller integer type 'Int' (aka 'int')}}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
void testLong(Long v) {
|
||||
|
|
Loading…
Reference in New Issue