]> granicus.if.org Git - clang/commitdiff
Separate the -Wnon-pod-memset warnings into two separate warnings:
authorDouglas Gregor <dgregor@apple.com>
Tue, 3 May 2011 20:05:22 +0000 (20:05 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 3 May 2011 20:05:22 +0000 (20:05 +0000)
  - a default-on warning for pointers to dynamic classes (= classes with vtables)
  - a default-off warning for other non-POD types

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130781 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaChecking.cpp
test/SemaCXX/warn-non-pod-memset.cpp

index aa7f64a24668f9b5d5eb695b9b2d7a560339f626..7056fbc9283275101d0a75bffe2aa210dfed69ea 100644 (file)
@@ -261,6 +261,9 @@ def err_builtin_definition : Error<"definition of builtin function %0">;
 def err_types_compatible_p_in_cplusplus : Error<
   "__builtin_types_compatible_p is not valid in C++">;
 def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError;
+def warn_dyn_class_memset : Warning<
+  "destination for this memset call is a pointer to a dynamic class %0">, 
+  InGroup<DiagGroup<"non-pod-memset">>;
 def warn_non_pod_memset : Warning<
   "destination for this memset call is a pointer to a non-POD type %0">,
   InGroup<DiagGroup<"non-pod-memset">>, DefaultIgnore;
index ee1a924e5a1ee50fabad85310ab412298737c23c..76f20ce530c28bece4d8b5ed32418f45f9e13ee7 100644 (file)
@@ -1799,6 +1799,17 @@ void Sema::CheckFormatString(const StringLiteral *FExpr,
 
 //===--- CHECK: Standard memory functions ---------------------------------===//
 
+/// \brief Determine whether the given type is a dynamic class type (e.g.,
+/// whether it has a vtable).
+static bool isDynamicClassType(QualType T) {
+  if (CXXRecordDecl *Record = T->getAsCXXRecordDecl())
+    if (CXXRecordDecl *Definition = Record->getDefinition())
+      if (Definition->isDynamicClass())
+        return true;
+  
+  return false;
+}
+
 /// \brief Check for dangerous or invalid arguments to memset().
 ///
 /// This issues warnings on known problematic or dangerous or unspecified
@@ -1814,27 +1825,26 @@ void Sema::CheckMemsetArguments(const CallExpr *Call) {
 
   const Expr *Dest = Call->getArg(0)->IgnoreParenImpCasts();
 
-  // The type checking for this warning is moderately expensive, only do it
-  // when enabled.
-  if (getDiagnostics().getDiagnosticLevel(diag::warn_non_pod_memset,
-                                          Dest->getExprLoc()) ==
-      Diagnostic::Ignored)
-    return;
-
   QualType DestTy = Dest->getType();
   if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) {
     QualType PointeeTy = DestPtrTy->getPointeeType();
     if (PointeeTy->isVoidType())
       return;
 
+    unsigned DiagID = 0;
+    // Always complain about dynamic classes.
+    if (isDynamicClassType(PointeeTy))
+      DiagID = diag::warn_dyn_class_memset;
     // Check the C++11 POD definition regardless of language mode; it is more
-    // relaxed than earlier definitions and we don't want spurrious warnings.
-    if (PointeeTy->isCXX11PODType())
+    // relaxed than earlier definitions and we don't want spurious warnings.
+    else if (!PointeeTy->isCXX11PODType())
+      DiagID = diag::warn_non_pod_memset;
+    else
       return;
 
     DiagRuntimeBehavior(
       Dest->getExprLoc(), Dest,
-      PDiag(diag::warn_non_pod_memset)
+      PDiag(DiagID)
         << PointeeTy << Call->getCallee()->getSourceRange());
 
     SourceRange ArgRange = Call->getArg(0)->getSourceRange();
index 9023793bd52d19c9342ef793e3d9a95f2251a7d5..6b017f338b00826dc4b34a3fa4798378e2b7e534 100644 (file)
@@ -30,13 +30,13 @@ void test_warn() {
       // expected-warning {{destination for this memset call is a pointer to a 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 a non-POD type}} \
+      // expected-warning {{destination for this memset call is a pointer to a 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 a 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 a non-POD type}} \
+      // expected-warning {{destination for this memset call is a pointer to a dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
 }