[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