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

On Jul 25, 2012, at 5:22 PM, Ted Kremenek <[email protected]> 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.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to