Index: lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp +++ 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; Index: test/Analysis/cxx-uninitialized-object-ptr-ref.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-ptr-ref.cpp +++ test/Analysis/cxx-uninitialized-object-ptr-ref.cpp @@ -416,14 +416,12 @@ #ifdef PEDANTIC struct PointerToMemberFunctionTest1 { - // TODO: we'd expect the note {{uninitialized field 'this->f'}} - void (UsefulFunctions::*f)(void); // no-note + void (UsefulFunctions::*f)(void); // expected-note{{uninitialized field 'this->f'}} PointerToMemberFunctionTest1() {} }; void fPointerToMemberFunctionTest1() { - // TODO: we'd expect the warning {{1 uninitialized field}} - PointerToMemberFunctionTest1(); // no-warning + PointerToMemberFunctionTest1(); // expected-warning{{1 uninitialized field}} } struct PointerToMemberFunctionTest2 { @@ -460,14 +458,12 @@ } struct PointerToMemberDataTest1 { - // TODO: we'd expect the note {{uninitialized field 'this->f'}} - int UsefulFunctions::*d; // no-note + int UsefulFunctions::*d; // expected-note{{uninitialized field 'this->d'}} PointerToMemberDataTest1() {} }; void fPointerToMemberDataTest1() { - // TODO: we'd expect the warning {{1 uninitialized field}} - PointerToMemberDataTest1(); // no-warning + PointerToMemberDataTest1(); // expected-warning{{1 uninitialized field}} } struct PointerToMemberDataTest2 {