[analyzer][UninitializedObjectChecker] Support for MemberPointerTypes

Differential Revision: https://reviews.llvm.org/D48325

llvm-svn: 336994
diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
index 016be6f..a44ae9c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
@@ -131,12 +131,10 @@
   //     - a non-union record
   //     - a pointer/reference
   //     - an array
-  //     - of a member pointer type
-  //     - of a primitive type, which we'll define as either a BuiltinType or
-  //       EnumeralType.
+  //     - of a primitive type, which we'll define later in a helper function.
   //   * the parent of each node is the object that contains it
-  //   * every leaf is an array, a primitive object, a member pointer, a nullptr
-  //     or an undefined pointer.
+  //   * every leaf is an array, a primitive object, a nullptr or an undefined
+  //   pointer.
   //
   // Example:
   //
@@ -163,8 +161,8 @@
   //
   // From this we'll construct a vector of fieldchains, where each fieldchain
   // represents an uninitialized field. An uninitialized field may be a
-  // primitive object, a member pointer, a pointer, a pointee or a union without
-  // a single initialized field.
+  // primitive object, a pointer, a pointee or a union without a single
+  // initialized field.
   // In the above example, for the default constructor call we'll end up with
   // these fieldchains:
   //
@@ -189,10 +187,6 @@
   bool isPointerOrReferenceUninit(const FieldRegion *FR,
                                   FieldChainInfo LocalChain);
 
-  /// This method checks a region of MemberPointerType, and returns true if the
-  /// the pointer is uninitialized.
-  bool isMemberPointerUninit(const FieldRegion *FR, FieldChainInfo LocalChain);
-
   /// This method returns true if the value of a primitive object is
   /// uninitialized.
   bool isPrimitiveUninit(const SVal &V);
@@ -225,10 +219,13 @@
 /// known, and thus FD can not be analyzed.
 static bool isVoidPointer(const FieldDecl *FD);
 
-/// Returns true if T is a primitive type. We'll call a type primitive if it's
-/// either a BuiltinType or an EnumeralType.
+/// Returns true if T is a primitive type. We defined this type so that for
+/// objects that we'd only like analyze as much as checking whether their
+/// value is undefined or not, such as ints and doubles, can be analyzed with
+/// ease. This also helps ensuring that every special field type is handled
+/// correctly.
 static bool isPrimitiveType(const QualType &T) {
-  return T->isBuiltinType() || T->isEnumeralType();
+  return T->isBuiltinType() || T->isEnumeralType() || T->isMemberPointerType();
 }
 
 /// Constructs a note message for a given FieldChainInfo object.
@@ -392,13 +389,6 @@
       continue;
     }
 
-    if (T->isMemberPointerType()) {
-      if (isMemberPointerUninit(FR, LocalChain))
-        ContainsUninitField = true;
-      continue;
-    }
-
-    // If this is a pointer or reference type.
     if (T->isPointerType() || T->isReferenceType()) {
       if (isPointerOrReferenceUninit(FR, LocalChain))
         ContainsUninitField = true;
@@ -542,14 +532,6 @@
   return false;
 }
 
-bool FindUninitializedFields::isMemberPointerUninit(const FieldRegion *FR,
-                                                    FieldChainInfo LocalChain) {
-  assert(FR->getDecl()->getType()->isMemberPointerType() &&
-         "This function only checks regions that hold MemberPointerTypes!");
-  // TODO: Implement support for MemberPointerTypes.
-  return false;
-}
-
 bool FindUninitializedFields::isPrimitiveUninit(const SVal &V) {
   if (V.isUndef())
     return true;