[cfe-commits] r160530 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h lib/StaticAnalyzer/Core/CheckerManager.cpp lib/StaticAnalyzer/Core/ExprEngineCXX.cpp lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp lib/StaticAnalyzer/Core/ExprEngineObjC.cpp

Jordan Rose jordan_rose at apple.com
Thu Jul 19 17:21:36 PDT 2012


It came out very nicely!

A few small comments...

On Jul 19, 2012, at 4:38 PM, Anna Zaks wrote:

> +
> +  /// \bried Default implementation of call evaluation.
> +  void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
>                        const CallEvent &Call);

Typo: "bried".


> +ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
> +                                            const LocationContext *LCtx,
> +                                            ProgramStateRef State) {
> +  const Expr *E = Call.getOriginExpr();
> +  if (!E)
> +    return State;
> +
> +  // Some method families have known return values.
> +  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
> +    switch (Msg->getMethodFamily()) {
> +    default:
> +      break;
> +    case OMF_autorelease:
> +    case OMF_retain:
> +    case OMF_self: {
> +      // These methods return their receivers.
> +      return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
> +      break;
> +    }
> +    }
> +  }

The inner braces are not necessary anymore here. Also, you have a break after a return.


> +void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
>                                  const CallEvent &Call) {
> +  ProgramStateRef State = 0;
> +  const Expr *E = Call.getOriginExpr();
> +
>   // Try to inline the call.
>   // The origin expression here is just used as a kind of checksum;
>   // for CallEvents that do not have origin expressions, this should still be
>   // safe.
> -  const Expr *E = Call.getOriginExpr();
> -  ProgramStateRef state = getInlineFailedState(Pred, E);
> -  if (state == 0 && inlineCall(Dst, Call, Pred))
> -    return;
> +  if (!isa<ObjCMethodCall>(Call)) {
> +    State = getInlineFailedState(Pred->getState(), E);
> +    if (State == 0 && inlineCall(Call, Pred)) {
> +      // If we inlined the call, the successor has been manually added onto
> +      // the work list and we should not consider it for subsequent call
> +      // handling steps.
> +      Bldr.takeNodes(Pred);
> +      return;
> +    }
> +  }
>  

I would just take out the check for isa<ObjCMethodCall>. The check for "dynamic dispatch" inside inlineCall should catch this, and getInlineFailedState isn't too expensive.



> @@ -182,13 +180,19 @@
> 
>         // Check if the "raise" message was sent.
>         assert(notNilState);
> -        if (msg.getSelector() == RaiseSel)
> -          RaisesException = true;
> +        if (msg.getSelector() == RaiseSel) {
> +          // If we raise an exception, for now treat it as a sink.
> +          // Eventually we will want to handle exceptions properly.
> +          Bldr.generateNode(currentStmt, Pred, Pred->getState(), true);
> +          continue;
> +        }
> 
> -        // If we raise an exception, for now treat it as a sink.
> -        // Eventually we will want to handle exceptions properly.
> -        // Dispatch to plug-in transfer function.
> -        evalObjCMessage(Bldr, msg, Pred, notNilState, RaisesException);
> +        // Generate a transition to non-Nil state.
> +        if (notNilState != state)
> +          Pred = Bldr.generateNode(currentStmt, Pred, notNilState);
> +
> +        // Evaluate the call.
> +        defaultEvalCall(Bldr, Pred, msg);
>       }
>     } else {
>       // Check for special class methods.
> @@ -222,19 +226,25 @@
>           }
> 
>           Selector S = msg.getSelector();
> +          bool RaisesException = false;
>           for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i) {
>             if (S == NSExceptionInstanceRaiseSelectors[i]) {
>               RaisesException = true;
>               break;
>             }
>           }
> +          if (RaisesException) {
> +            // If we raise an exception, for now treat it as a sink.
> +            // Eventually we will want to handle exceptions properly.
> +            Bldr.generateNode(currentStmt, Pred, Pred->getState(), true);
> +            continue;
> +          }
> +
>         }
>       }
> 
> -      // If we raise an exception, for now treat it as a sink.
> -      // Eventually we will want to handle exceptions properly.
> -      // Dispatch to plug-in transfer function.
> -      evalObjCMessage(Bldr, msg, Pred, Pred->getState(), RaisesException);
> +      // Evaluate the call.
> +      defaultEvalCall(Bldr, Pred, msg);
>     }
>   }

You can probably merge some pieces of the two branches now (the class and instance method branches).



More information about the cfe-commits mailing list