Separate the -Wnon-pod-memset warnings into two separate warnings:
  - 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
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index ee1a924..76f20ce 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1799,6 +1799,17 @@
 
 //===--- 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 @@
 
   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();