[cfe-commits] r132534 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/SemaCXX/warn-bad-memaccess.cpp test/SemaCXX/warn-non-pod-memset.cpp

Chandler Carruth chandlerc at gmail.com
Thu Jun 2 23:23:57 PDT 2011


Author: chandlerc
Date: Fri Jun  3 01:23:57 2011
New Revision: 132534

URL: http://llvm.org/viewvc/llvm-project?rev=132534&view=rev
Log:
Clean up the "non-POD memaccess" stuff some. This adds a properly named
diagnostic group to cover the cases where we have definitively bad
behavior: dynamic classes.

It also rips out the existing support for POD-based checking. This
didn't work well, and triggered too many false positives. I'm looking
into a possibly more principled way to warn on the fundamental buggy
construct here. POD-ness isn't the critical aspect anyways, so a clean
slate is better. This also removes some silliness from the code until
the new checks arrive.

Added:
    cfe/trunk/test/SemaCXX/warn-bad-memaccess.cpp
      - copied, changed from r132531, cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp
Removed:
    cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaChecking.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=132534&r1=132533&r2=132534&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun  3 01:23:57 2011
@@ -264,12 +264,8 @@
 def warn_dyn_class_memaccess : Warning<
   "%select{destination for|source of}0 this %1 call is a pointer to dynamic "
   "class %2; vtable pointer will be overwritten">, 
-  InGroup<DiagGroup<"non-pod-memaccess">>;
-def warn_non_pod_memaccess : Warning<
-  "%select{destination for|source of}0 this %1 call is a pointer to non-POD "
-  "type %2">,
-  InGroup<DiagGroup<"non-pod-memaccess">>, DefaultIgnore;
-def note_non_pod_memaccess_silence : Note<
+  InGroup<DiagGroup<"dynamic-class-memaccess">>;
+def note_bad_memaccess_silence : Note<
   "explicitly cast the pointer to silence this warning">;
 
 /// main()

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=132534&r1=132533&r2=132534&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Jun  3 01:23:57 2011
@@ -1814,7 +1814,7 @@
 
 /// \brief Check for dangerous or invalid arguments to memset().
 ///
-/// This issues warnings on known problematic or dangerous or unspecified
+/// This issues warnings on known problematic, dangerous or unspecified
 /// arguments to the standard 'memset', 'memcpy', and 'memmove' function calls.
 ///
 /// \param Call The call expression to diagnose.
@@ -1836,27 +1836,21 @@
       if (PointeeTy->isVoidType())
         continue;
 
-      unsigned DiagID = 0;
       // Always complain about dynamic classes.
-      if (isDynamicClassType(PointeeTy))
-        DiagID = diag::warn_dyn_class_memaccess;
-      // Check the C++11 POD definition regardless of language mode; it is more
-      // relaxed than earlier definitions and we don't want spurious warnings.
-      else if (!PointeeTy->isCXX11PODType())
-        DiagID = diag::warn_non_pod_memaccess;
-      else
+      if (isDynamicClassType(PointeeTy)) {
+        DiagRuntimeBehavior(
+          Dest->getExprLoc(), Dest,
+          PDiag(diag::warn_dyn_class_memaccess)
+            << ArgIdx << FnName << PointeeTy 
+            << Call->getCallee()->getSourceRange());
+      } else {
         continue;
-
-      DiagRuntimeBehavior(
-        Dest->getExprLoc(), Dest,
-        PDiag(DiagID)
-          << ArgIdx << FnName << PointeeTy 
-          << Call->getCallee()->getSourceRange());
+      }
 
       SourceRange ArgRange = Call->getArg(0)->getSourceRange();
       DiagRuntimeBehavior(
         Dest->getExprLoc(), Dest,
-        PDiag(diag::note_non_pod_memaccess_silence)
+        PDiag(diag::note_bad_memaccess_silence)
           << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)"));
       break;
     }

Copied: cfe/trunk/test/SemaCXX/warn-bad-memaccess.cpp (from r132531, cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-bad-memaccess.cpp?p2=cfe/trunk/test/SemaCXX/warn-bad-memaccess.cpp&p1=cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp&r1=132531&r2=132534&rev=132534&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-bad-memaccess.cpp Fri Jun  3 01:23:57 2011
@@ -1,57 +1,42 @@
-// RUN: %clang_cc1 -fsyntax-only -Wnon-pod-memaccess -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s
 
 extern "C" void *memset(void *, int, unsigned);
 extern "C" void *memmove(void *s1, const void *s2, unsigned n);
 extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
 
-// Several POD types that should not warn.
+// Several types that should not warn.
 struct S1 {} s1;
 struct S2 { int x; } s2;
 struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
 
-// We use the C++11 concept of POD for this warning, so ensure a non-aggregate
-// still warns.
 class C1 {
   int x, y, z;
 public:
   void foo() {}
 } c1;
 
-// Non-POD types that should warn.
-struct X1 { X1(); } x1;
-struct X2 { ~X2(); } x2;
-struct X3 { virtual void f(); } x3;
-struct X4 : X2 {} x4;
-struct X5 : virtual S1 {} x5;
+struct X1 { virtual void f(); } x1;
+struct X2 : virtual S1 {} x2;
 
 void test_warn() {
   memset(&x1, 0, sizeof x1); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to non-POD type}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x2, 0, sizeof x2); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to non-POD type}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x3, 0, sizeof x3); // \
       // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x4, 0, sizeof x4); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to non-POD type}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x5, 0, sizeof x5); // \
+  memset(&x2, 0, sizeof x2); // \
       // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
 
   memmove(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memmove' call is a pointer to non-POD type 'struct X1'}} \
+      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memmove(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memmove' call is a pointer to non-POD type 'struct X1'}} \
+      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcpy(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memcpy' call is a pointer to non-POD type 'struct X1'}} \
+      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcpy(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memcpy' call is a pointer to non-POD type 'struct X1'}} \
+      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
 }
 

Removed: cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp?rev=132533&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp (removed)
@@ -1,85 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -Wnon-pod-memaccess -verify %s
-
-extern "C" void *memset(void *, int, unsigned);
-extern "C" void *memmove(void *s1, const void *s2, unsigned n);
-extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
-
-// Several POD types that should not warn.
-struct S1 {} s1;
-struct S2 { int x; } s2;
-struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
-
-// We use the C++11 concept of POD for this warning, so ensure a non-aggregate
-// still warns.
-class C1 {
-  int x, y, z;
-public:
-  void foo() {}
-} c1;
-
-// Non-POD types that should warn.
-struct X1 { X1(); } x1;
-struct X2 { ~X2(); } x2;
-struct X3 { virtual void f(); } x3;
-struct X4 : X2 {} x4;
-struct X5 : virtual S1 {} x5;
-
-void test_warn() {
-  memset(&x1, 0, sizeof x1); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to non-POD type}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x2, 0, sizeof x2); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to non-POD type}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x3, 0, sizeof x3); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x4, 0, sizeof x4); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to non-POD type}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memset(&x5, 0, sizeof x5); // \
-      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-
-  memmove(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memmove' call is a pointer to non-POD type 'struct X1'}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memmove(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memmove' call is a pointer to non-POD type 'struct X1'}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memcpy(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memcpy' call is a pointer to non-POD type 'struct X1'}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-  memcpy(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memcpy' call is a pointer to non-POD type 'struct X1'}} \
-      // expected-note {{explicitly cast the pointer to silence this warning}}
-}
-
-void test_nowarn(void *void_ptr) {
-  int i, *iptr;
-  float y;
-  char c;
-
-  memset(&i, 0, sizeof i);
-  memset(&iptr, 0, sizeof iptr);
-  memset(&y, 0, sizeof y);
-  memset(&c, 0, sizeof c);
-  memset(void_ptr, 0, 42);
-  memset(&s1, 0, sizeof s1);
-  memset(&s2, 0, sizeof s2);
-  memset(&s3, 0, sizeof s3);
-  memset(&c1, 0, sizeof c1);
-
-  // Unevaluated code shouldn't warn.
-  (void)sizeof memset(&x1, 0, sizeof x1);
-
-  // Dead code shouldn't warn.
-  if (false) memset(&x1, 0, sizeof x1);
-}
-
-namespace N {
-  void *memset(void *, int, unsigned);
-  void test_nowarn() {
-    N::memset(&x1, 0, sizeof x1);
-  }
-}





More information about the cfe-commits mailing list