Hello!

I'd like to get comments / reviews for this patch.

clang currently writes warnings if memset is used on a class that contains 
virtual methods.

This patch adds warnings when memset is used on a class that contains std class 
members. This can cause weird bugs.

I have seen such bugs in a closed source project. And there was also a major 
cleanup of such bugs a few years ago in boinc.

Best regards,
Daniel Marjamäki

..................................................................................................................
Daniel Marjamäki
Senior Engineer
Evidente ES East AB 
Warfvinges väg 34  SE-112 51 Stockholm  Sweden 

 
Mobile:                
+46 (0)709 12 42 62
E-mail:   
             
[email protected]     
                 
 
www.evidente.se







Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp	(revision 194617)
+++ lib/Sema/SemaChecking.cpp	(arbetskopia)
@@ -3584,6 +3584,32 @@
   return QualType();
 }
 
+static bool hasStdMember(const QualType PointeeTy) {
+  if (!PointeeTy->isRecordType())
+    return false;
+  const CXXRecordDecl *RD = PointeeTy->getAsCXXRecordDecl();
+  if (!RD)
+    return false;
+  const DeclContext *DC = dyn_cast<DeclContext>(RD);
+  if (!DC)
+    return false;
+  for (DeclContext::decl_iterator I = DC->noload_decls_begin(),
+                                  E = DC->noload_decls_end();
+       I != E; ++I) {
+    const FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*I);
+    if (!MemberDecl)
+      continue;
+    const QualType MemberType = MemberDecl->getType();
+    if (MemberType->isRecordType() && !MemberType->hasPointerRepresentation() &&
+        MemberType->getAsCXXRecordDecl() &&
+        MemberType->getAsCXXRecordDecl()->hasUserDeclaredConstructor() &&
+        QualType::getAsString(MemberType.split()).compare(0, 5, "std::") == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
 /// \brief Check for dangerous or invalid arguments to memset().
 ///
 /// This issues warnings on known problematic, dangerous or unspecified
@@ -3721,6 +3747,10 @@
             << FnName << PointeeTy
             << OperationType
             << Call->getCallee()->getSourceRange());
+      } else if (hasStdMember(PointeeTy)) {
+        DiagRuntimeBehavior(Dest->getExprLoc(), Dest,
+                            PDiag(diag::warn_std_class_memaccess));
+        continue;
       } else if (PointeeTy.hasNonTrivialObjCLifetime() &&
                BId != Builtin::BImemset)
         DiagRuntimeBehavior(
Index: test/SemaCXX/warn-bad-memaccess.cpp
===================================================================
--- test/SemaCXX/warn-bad-memaccess.cpp	(revision 194617)
+++ test/SemaCXX/warn-bad-memaccess.cpp	(arbetskopia)
@@ -120,3 +120,23 @@
     N::memset(&x1, 0, sizeof x1);
   }
 }
+
+// test string class in std namespace
+namespace std {
+  class string {
+  private:
+    char *somedata;
+  public:
+    string();
+    string(const char *);
+  };
+};
+
+struct Std1 {
+  std::string str1;
+};
+
+void test_warn_std() {
+  struct Std1 s1;
+  memset(&s1, 0, sizeof s1); // expected-warning{{memset of class that contains std class members}}
+}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 194617)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(arbetskopia)
@@ -374,6 +374,9 @@
   InGroup<DiagGroup<"dynamic-class-memaccess">>;
 def note_bad_memaccess_silence : Note<
   "explicitly cast the pointer to silence this warning">;
+def warn_std_class_memaccess : Warning<
+  "memset of class that contains std class members">,
+  InGroup<DiagGroup<"std-class-memaccess">>;
 def warn_sizeof_pointer_expr_memaccess : Warning<
   "'%0' call operates on objects of type %1 while the size is based on a " 
   "different type %2">, 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to