[cfe-commits] r166039 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaCast.cpp test/Analysis/CFContainers.mm test/Analysis/idempotent-operations.c test/Analysis/misc-ps-region-store.m test/Analysis/taint-tester.c test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp test/Sema/block-return.c test/Sema/cast.c test/Sema/i-c-e.c test/SemaCXX/cast-conversion.cpp test/SemaCXX/decl-expr-ambiguity.cpp
David Blaikie
dblaikie at gmail.com
Tue Oct 16 11:53:14 PDT 2012
Author: dblaikie
Date: Tue Oct 16 13:53:14 2012
New Revision: 166039
URL: http://llvm.org/viewvc/llvm-project?rev=166039&view=rev
Log:
Implement GCC's -Wint-to-pointer-cast.
This implementation doesn't warn on anything that GCC doesn't warn on with the
exception of templates specializations (GCC doesn't warn, Clang does). The
specific skipped cases (boolean, constant expressions, enums) are open for
debate/adjustment if anyone wants to demonstrate that GCC is being overly
conservative here. The only really obvious false positive I found was in the
Clang regression suite's MPI test - apparently MPI uses specific flag values in
pointer constants. (eg: #define FOO (void*)~0)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaCast.cpp
cfe/trunk/test/Analysis/CFContainers.mm
cfe/trunk/test/Analysis/idempotent-operations.c
cfe/trunk/test/Analysis/misc-ps-region-store.m
cfe/trunk/test/Analysis/taint-tester.c
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
cfe/trunk/test/Sema/block-return.c
cfe/trunk/test/Sema/cast.c
cfe/trunk/test/Sema/i-c-e.c
cfe/trunk/test/SemaCXX/cast-conversion.cpp
cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Oct 16 13:53:14 2012
@@ -365,6 +365,8 @@
def TypeSafety : DiagGroup<"type-safety">;
+def IntToPointerCast : DiagGroup<"int-to-pointer-cast">;
+
def Extra : DiagGroup<"extra", [
MissingFieldInitializers,
IgnoredQualifiers,
@@ -412,7 +414,7 @@
// Note that putting warnings in -Wall will not disable them by default. If a
// warning should be active _only_ when -Wall is passed in, mark it as
// DefaultIgnore in addition to putting it here.
-def : DiagGroup<"all", [Most, Parentheses, Switch]>;
+def : DiagGroup<"all", [Most, Parentheses, Switch, IntToPointerCast]>;
// Warnings enabled by -pedantic. This is magically filled in by TableGen.
def Pedantic : DiagGroup<"pedantic">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 16 13:53:14 2012
@@ -1995,6 +1995,10 @@
"cast from %0 to %1 increases required alignment from %2 to %3">,
InGroup<CastAlign>, DefaultIgnore;
+def warn_int_to_pointer_cast : Warning<
+ "cast to %1 from smaller integer type %0">,
+ InGroup<IntToPointerCast>;
+
def warn_attribute_ignored_for_field_of_type : Warning<
"%0 attribute ignored for field of type %1">,
InGroup<IgnoredAttributes>;
Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Tue Oct 16 13:53:14 2012
@@ -1491,6 +1491,22 @@
}
}
+static void checkIntToPointerCast(bool CStyle, SourceLocation Loc,
+ const Expr *SrcExpr, QualType DestType,
+ Sema &Self) {
+ QualType SrcType = SrcExpr->getType();
+
+ // Not warning on reinterpret_cast, boolean, constant expressions, etc
+ // are not explicit design choices, but consistent with GCC's behavior.
+ // Feel free to modify them if you've reason/evidence for an alternative.
+ if (CStyle && SrcType->isIntegralType(Self.Context)
+ && !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;
+}
+
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
@@ -1689,6 +1705,8 @@
if (SrcType->isIntegralOrEnumerationType()) {
assert(destIsPtr && "One type must be a pointer");
+ checkIntToPointerCast(CStyle, OpRange.getBegin(), SrcExpr.get(), DestType,
+ Self);
// C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
// converted to a pointer.
// C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not
@@ -2071,6 +2089,8 @@
SrcExpr = ExprError();
return;
}
+ checkIntToPointerCast(/* CStyle */ true, OpRange.getBegin(), SrcExpr.get(),
+ DestType, Self);
} else if (!SrcType->isArithmeticType()) {
if (!DestType->isIntegralType(Self.Context) &&
DestType->isArithmeticType()) {
Modified: cfe/trunk/test/Analysis/CFContainers.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/CFContainers.mm?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/CFContainers.mm (original)
+++ cfe/trunk/test/Analysis/CFContainers.mm Tue Oct 16 13:53:14 2012
@@ -125,7 +125,7 @@
const CFDictionaryKeyCallBacks keyCB = kCFCopyStringDictionaryKeyCallBacks;
const CFDictionaryValueCallBacks valCB = kCFTypeDictionaryValueCallBacks;
CFDictionaryRef dict1 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, numValues, &keyCB, &valCB); // no warning
- CFDictionaryRef dict2 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)elems[0], (const void**)values, numValues, &keyCB, &valCB); //expected-warning {{The second argument to 'CFDictionaryCreate' must be a C array of}}
+ CFDictionaryRef dict2 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)elems[0], (const void**)values, numValues, &keyCB, &valCB); //expected-warning {{The second argument to 'CFDictionaryCreate' must be a C array of}} expected-warning {{cast to 'const void **' from smaller integer type 'int'}}
CFDictionaryRef dict3 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)elems, numValues, &keyCB, &valCB); // expected-warning {{The third argument to 'CFDictionaryCreate' must be a C array of pointer-sized values}}
}
Modified: cfe/trunk/test/Analysis/idempotent-operations.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/idempotent-operations.c?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/idempotent-operations.c (original)
+++ cfe/trunk/test/Analysis/idempotent-operations.c Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=alpha.deadcode.IdempotentOperations -verify %s
+// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=alpha.deadcode.IdempotentOperations -verify %s
// Basic tests
Modified: cfe/trunk/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.m?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.m Tue Oct 16 13:53:14 2012
@@ -1086,6 +1086,9 @@
u_char *src = (u_char *) ((u_long) bootMP);
u_char *dst = (u_char *) boot_addr + ((vm_offset_t) ((((((((1 <<
12) / (sizeof(pd_entry_t))) - 1) - 1) - (260 - 2))) << 22) | ((0) << 12)));
+#ifdef TEST_64
+// expected-warning at -3 {{cast to 'u_char *' (aka 'unsigned char *') from smaller integer type 'u_int' (aka 'unsigned int')}}
+#endif
for (x = 0;
x < size;
++x)
Modified: cfe/trunk/test/Analysis/taint-tester.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-tester.c?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/taint-tester.c (original)
+++ cfe/trunk/test/Analysis/taint-tester.c Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
#include <stdarg.h>
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp Tue Oct 16 13:53:14 2012
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fcxx-exceptions %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -verify -std=c++11 -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s
namespace StdExample {
@@ -80,7 +80,7 @@
// __builtin_constant_p ? : is magical, and is always a potential constant.
constexpr bool BcpCall(int n) {
- return __builtin_constant_p((int*)n != &n) ? (int*)n != &n : (int*)n != &n;
+ return __builtin_constant_p((int*)n != &n) ? (int*)n != &n : (int*)n != &n; // expected-warning 3 {{cast to 'int *' from smaller integer type 'int'}}
}
static_assert(BcpCall(0), "");
Modified: cfe/trunk/test/Sema/block-return.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-return.c?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Sema/block-return.c (original)
+++ cfe/trunk/test/Sema/block-return.c Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -pedantic -fsyntax-only %s -verify -fblocks
+// RUN: %clang_cc1 -Wno-int-to-pointer-cast -pedantic -fsyntax-only %s -verify -fblocks
typedef void (^CL)(void);
Modified: cfe/trunk/test/Sema/cast.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/cast.c?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Sema/cast.c (original)
+++ cfe/trunk/test/Sema/cast.c Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s -verify
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown %s -verify
typedef struct { unsigned long bits[(((1) + (64) - 1) / (64))]; } cpumask_t;
cpumask_t x;
@@ -52,8 +52,8 @@
(void) (CLong) v;
(void) (CFloat) v;
(void) (CDouble) v;
- (void) (VoidPtr) v;
- (void) (CharPtr) 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')}}
}
void testLong(Long v) {
@@ -157,3 +157,12 @@
(void) (VoidPtr) v;
(void) (CharPtr) v;
}
+
+typedef enum { x_a, x_b } X;
+void *intToPointerCast2(X x) {
+ return (void*)x;
+}
+
+void *intToPointerCast3() {
+ return (void*)(1 + 3);
+}
Modified: cfe/trunk/test/Sema/i-c-e.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/i-c-e.c?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/Sema/i-c-e.c (original)
+++ cfe/trunk/test/Sema/i-c-e.c Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang %s -ffreestanding -fsyntax-only -Xclang -verify -pedantic -fpascal-strings -std=c99
+// RUN: %clang %s -ffreestanding -Wno-int-to-pointer-cast -fsyntax-only -Xclang -verify -pedantic -fpascal-strings -std=c99
#include <stdint.h>
#include <limits.h>
Modified: cfe/trunk/test/SemaCXX/cast-conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cast-conversion.cpp?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cast-conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/cast-conversion.cpp Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -verify %s -std=c++11
struct R {
R(int);
@@ -45,3 +45,23 @@
static_cast<float*>(f0<0>()); // expected-error{{ambiguous}}
}
};
+
+void *intToPointer1(short s) {
+ return (void*)s; // expected-warning{{cast to 'void *' from smaller integer type 'short'}}
+}
+
+void *intToPointer2(short s) {
+ return reinterpret_cast<void*>(s);
+}
+
+void *intToPointer3(bool b) {
+ return (void*)b;
+}
+
+void *intToPointer4() {
+ return (void*)(3 + 7);
+}
+
+void *intToPointer5(long l) {
+ return (void*)l;
+}
Modified: cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp?rev=166039&r1=166038&r2=166039&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp Tue Oct 16 13:53:14 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic-errors %s
+// RUN: %clang_cc1 -Wno-int-to-pointer-cast -fsyntax-only -verify -pedantic-errors %s
void f() {
int a;
More information about the cfe-commits
mailing list