Index: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -379,6 +379,17 @@ return RetTy; } +static Optional refValFromRetEffect(RetEffect RE, + QualType ResultTy) { + if (RE.isOwned()) { + return RefVal::makeOwned(RE.getObjKind(), ResultTy); + } else if (RE.notOwned()) { + return RefVal::makeNotOwned(RE.getObjKind(), ResultTy); + } + + return None; +} + // We don't always get the exact modeling of the function with regards to the // retain count checker even when the function is inlined. For example, we need // to stop tracking the symbols which were marked with StopTrackingHard. @@ -515,43 +526,15 @@ RE = RetEffect::MakeNoRet(); } - switch (RE.getKind()) { - default: - llvm_unreachable("Unhandled RetEffect."); - - case RetEffect::NoRet: - case RetEffect::NoRetHard: - // No work necessary. - break; - - case RetEffect::OwnedSymbol: { - SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol(); - if (!Sym) - break; - - // Use the result type from the CallEvent as it automatically adjusts - // for methods/functions that return references. - QualType ResultTy = CallOrMsg.getResultType(); - state = setRefBinding(state, Sym, RefVal::makeOwned(RE.getObjKind(), - ResultTy)); - - // FIXME: Add a flag to the checker where allocations are assumed to - // *not* fail. - break; - } - - case RetEffect::NotOwnedSymbol: { + if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) { + QualType ResultTy = CallOrMsg.getResultType(); + if (RE.notOwned()) { const Expr *Ex = CallOrMsg.getOriginExpr(); - SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol(); - if (!Sym) - break; assert(Ex); - // Use GetReturnType in order to give [NSFoo alloc] the type NSFoo *. - QualType ResultTy = GetReturnType(Ex, C.getASTContext()); - state = setRefBinding(state, Sym, RefVal::makeNotOwned(RE.getObjKind(), - ResultTy)); - break; + ResultTy = GetReturnType(Ex, C.getASTContext()); } + if (Optional updatedRefVal = refValFromRetEffect(RE, ResultTy)) + state = setRefBinding(state, Sym, *updatedRefVal); } // This check is actually necessary; otherwise the statement builder thinks