[cfe-commits] r160767 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp test/Analysis/misc-ps-cxx0x.cpp

Jordan Rose jordan_rose at apple.com
Wed Jul 25 21:15:48 PDT 2012


Nice. So that's what's going on with CallAndMessageChecker!

On Jul 25, 2012, at 5:22 PM, Ted Kremenek <kremenek at apple.com> wrote:

> Author: kremenek
> Date: Wed Jul 25 19:22:32 2012
> New Revision: 160767
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=160767&view=rev
> Log:
> Add static analyzer check for calling a C++ instance method with a null/uninitialized pointer.
> 
> Modified:
>    cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
>    cfe/trunk/test/Analysis/misc-ps-cxx0x.cpp
> 
> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=160767&r1=160766&r2=160767&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Wed Jul 25 19:22:32 2012
> @@ -31,6 +31,8 @@
>                     check::PreCall > {
>   mutable OwningPtr<BugType> BT_call_null;
>   mutable OwningPtr<BugType> BT_call_undef;
> +  mutable OwningPtr<BugType> BT_cxx_call_null;
> +  mutable OwningPtr<BugType> BT_cxx_call_undef;
>   mutable OwningPtr<BugType> BT_call_arg;
>   mutable OwningPtr<BugType> BT_msg_undef;
>   mutable OwningPtr<BugType> BT_objc_prop_undef;
> @@ -239,14 +241,35 @@
> 
> void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
>                                          CheckerContext &C) const {
> +  // If this is a call to a C++ method, check if the callee is null or
> +  // undefined.
> +  // FIXME: Generalize this to CXXInstanceCall once it supports
> +  // getCXXThisVal().

Right now, all CallEvents support getCXXThisVal(); it's type-dispatched. But outside of CXXInstanceCall, "UndefinedVal" is a placeholder for "no 'this' object". Any CXXInstanceCall should have a valid this-val though.


> +  if (const CXXMemberCall *CC = dyn_cast<CXXMemberCall>(&Call)) {
> +    SVal V = CC->getCXXThisVal();
> +    if (V.isUndef()) {
> +      if (!BT_cxx_call_undef)
> +        BT_cxx_call_undef.reset(new BuiltinBug("Called C++ object pointer is "
> +                                               "uninitialized"));
> +      EmitBadCall(BT_cxx_call_undef.get(), C, CC->getOriginExpr());
> +      return;
> +    }
> +    if (V.isZeroConstant()) {
> +      if (!BT_cxx_call_null)
> +        BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
> +                                              "is null"));
> +      EmitBadCall(BT_cxx_call_null.get(), C, CC->getOriginExpr());
> +      return;
> +    }
> +  }
> +

This is probably the place to assume V is non-null if we call a method on it. Do we want to do that?

>   // Don't check for uninitialized field values in arguments if the
>   // caller has a body that is available and we have the chance to inline it.
>   // This is a hack, but is a reasonable compromise betweens sometimes warning
>   // and sometimes not depending on if we decide to inline a function.
>   const Decl *D = Call.getDecl();
>   const bool checkUninitFields =
> -    !(C.getAnalysisManager().shouldInlineCall() &&
> -      (D && D->getBody()));
> +    !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody())); 

Yeah, this should be refactored into CallEvent anyway, either CallEvent::mayBeInlined or CallEvent::willBeInlined. The test is wrong because a CallEvent's decl is often not the decl with the definition.



More information about the cfe-commits mailing list