Re: r345099 - [analyzer] Trust summaries for OSObject::retain and OSObject::release

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: r345099 - [analyzer] Trust summaries for OSObject::retain and OSObject::release

Oleg Smolsky via cfe-dev
The error is indeed strange.
The body is declared as

  LazyDeclStmtPtr Body;

where

using LazyDeclStmtPtr =
    LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;

where

template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
struct LazyOffsetPtr {
  mutable uint64_t Ptr = 0;
(…)
  explicit operator bool() const { return Ptr != 0; }
(…)
}

so it does not seem like it can be uninitialized.
Sadly on macOS I don’t have either valgrind or msan,
so I can’t reproduce the failure.
Do you think you could debug further?
Is “Body” indeed uninitialized at use time? (e.g. if you print it..)
A stacktrace from a debug build should be helpful.

Thanks,
George

On Nov 26, 2018, at 12:03 AM, Mikael Holmén <[hidden email]> wrote:

Hi again,

Do you have any opinion about the below valgrind complaint that starts 
appearing with this patch?

valgrind still complains on it on current trunk.

I see it when compiling with clang 3.6.0. I've also tried gcc 5.4.0 but 
then I don't get it.

Regards,
Mikael

On 11/21/18 8:33 AM, Mikael Holmén via cfe-commits wrote:
Hi George,

I noticed that valgrind started complaining in one case with this patch.

I've no idea if it's really due to something in the patch or if it's
something old that surfaced or if it's a false flag.

Anyway, with this patch the following

  valgrind clang-tidy -checks='-*,clang-analyzer-*' 'memcpy.c' -- -O0

gives me

==18829== Memcheck, a memory error detector
==18829== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==18829== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==18829== Command: build-all/bin/clang-tidy -checks=-*,clang-analyzer-*
memcpy.c -- -O0
==18829==
==18829== Conditional jump or move depends on uninitialised value(s)
==18829==    at 0xE580DF:
clang::ento::RetainSummaryManager::canEval(clang::CallExpr const*,
clang::FunctionDecl const*, bool&) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xD034AA:
clang::ento::retaincountchecker::RetainCountChecker::evalCall(clang::CallExpr
const*, clang::ento::CheckerContext&) const (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xDCBCD7:
clang::ento::CheckerManager::runCheckersForEvalCall(clang::ento::ExplodedNodeSet&,
clang::ento::ExplodedNodeSet const&, clang::ento::CallEvent const&,
clang::ento::ExprEngine&) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xE033D5:
clang::ento::ExprEngine::evalCall(clang::ento::ExplodedNodeSet&,
clang::ento::ExplodedNode*, clang::ento::CallEvent const&) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xE03165:
clang::ento::ExprEngine::VisitCallExpr(clang::CallExpr const*,
clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xDE3D9A: clang::ento::ExprEngine::Visit(clang::Stmt
const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xDDEFD1:
clang::ento::ExprEngine::ProcessStmt(clang::Stmt const*,
clang::ento::ExplodedNode*) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xDDEBBC:
clang::ento::ExprEngine::processCFGElement(clang::CFGElement,
clang::ento::ExplodedNode*, unsigned int,
clang::ento::NodeBuilderContext*) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xDD3154:
clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned
int, clang::ento::ExplodedNode*) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xDD24D3:
clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*,
unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>)
(in /data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xB8E90E: (anonymous
namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int,
clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl
const*, llvm::DenseMapInfo<clang::Decl const*> >*) (in
/data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==    by 0xB89943: (anonymous
namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&)
(in /data/repo/llvm-patch/build-all/bin/clang-tidy)
==18829==

The call to

     const FunctionDecl* FDD = FD->getDefinition();

in RetainSummaryManager::canEval eventually ends up in

   bool isThisDeclarationADefinition() const {
     return isDeletedAsWritten() || isDefaulted() || Body ||
hasSkippedBody() ||
            isLateTemplateParsed() || willHaveBody() || hasDefiningAttr();
   }

And here it seems to be the access of "Body" that valgrind complains on.
If I simply comment out "Body" the complaint is gone.

I really have no clue about this code, but perhaps this makes some sense
to you? Or perhaps to someone else?

Regards,
Mikael

On 10/24/18 1:11 AM, George Karpenkov via cfe-commits wrote:
Author: george.karpenkov
Date: Tue Oct 23 16:11:30 2018
New Revision: 345099

URL: http://llvm.org/viewvc/llvm-project?rev=345099&view=rev
Log:
[analyzer] Trust summaries for OSObject::retain and OSObject::release

Refactor the way in which summaries are consumed for safeMetaCast

Differential Revision: https://reviews.llvm.org/D53549

Modified:
     cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
     cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
     cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345099&r1=345098&r2=345099&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Tue Oct 23 16:11:30 2018
@@ -776,31 +776,27 @@ bool RetainCountChecker::evalCall(const

    const LocationContext *LCtx = C.getLocationContext();

-  // Process OSDynamicCast: should just return the first argument.
-  // For now, tresting the cast as a no-op, and disregarding the case where
-  // the output becomes null due to the type mismatch.
-  if (FD->getNameAsString() == "safeMetaCast") {
-    state = state->BindExpr(CE, LCtx,
-                            state->getSVal(CE->getArg(0), LCtx));
-    C.addTransition(state);
-    return true;
-  }
-
    // See if it's one of the specific functions we know how to eval.
    if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
      return false;

    // Bind the return value.
-  SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
-  if (RetVal.isUnknown() ||
-      (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+  // For now, all the functions which we can evaluate and which take
+  // at least one argument are identities.
+  if (CE->getNumArgs() >= 1) {
+    SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
+
      // If the receiver is unknown or the function has
      // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
      // return value.
-    SValBuilder &SVB = C.getSValBuilder();
-    RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+    if (RetVal.isUnknown() ||
+        (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+      SValBuilder &SVB = C.getSValBuilder();
+      RetVal =
+          SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+    }
+    state = state->BindExpr(CE, LCtx, RetVal, false);
    }
-  state = state->BindExpr(CE, LCtx, RetVal, false);

    C.addTransition(state);
    return true;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345099&r1=345098&r2=345099&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue Oct 23 16:11:30 2018
@@ -102,9 +102,6 @@ RetainSummaryManager::generateSummary(co
      return getPersistentStopSummary();
    }

-  // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the
-  // function's type.
-  const FunctionType *FT = FD->getType()->getAs<FunctionType>();
    const IdentifierInfo *II = FD->getIdentifier();
    if (!II)
      return getDefaultSummary();
@@ -115,7 +112,8 @@ RetainSummaryManager::generateSummary(co
    // down below.
    FName = FName.substr(FName.find_first_not_of('_'));

-  // Inspect the result type.
+  // Inspect the result type. Strip away any typedefs.
+  const auto *FT = FD->getType()->getAs<FunctionType>();
    QualType RetTy = FT->getReturnType();
    std::string RetTyName = RetTy.getAsString();

@@ -506,12 +504,6 @@ bool RetainSummaryManager::isTrustedRefe
  bool RetainSummaryManager::canEval(const CallExpr *CE,
                                     const FunctionDecl *FD,
                                     bool &hasTrustedImplementationAnnotation) {
-  // For now, we're only handling the functions that return aliases of their
-  // arguments: CFRetain (and its families).
-  // Eventually we should add other functions we can model entirely,
-  // such as CFRelease, which don't invalidate their arguments or globals.
-  if (CE->getNumArgs() != 1)
-    return false;

    IdentifierInfo *II = FD->getIdentifier();
    if (!II)
@@ -533,6 +525,13 @@ bool RetainSummaryManager::canEval(const
        return isRetain(FD, FName) || isAutorelease(FD, FName) ||
               isMakeCollectable(FName);

+    // Process OSDynamicCast: should just return the first argument.
+    // For now, treating the cast as a no-op, and disregarding the case where
+    // the output becomes null due to the type mismatch.
+    if (TrackOSObjects && FName == "safeMetaCast") {
+      return true;
+    }
+
      const FunctionDecl* FDD = FD->getDefinition();
      if (FDD && isTrustedReferenceCountImplementation(FDD)) {
        hasTrustedImplementationAnnotation = true;
@@ -540,6 +539,12 @@ bool RetainSummaryManager::canEval(const
      }
    }

+  if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    const CXXRecordDecl *Parent = MD->getParent();
+    if (TrackOSObjects && Parent && isOSObjectSubclass(Parent))
+      return FName == "release" || FName == "retain";
+  }
+
    return false;

  }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345099&r1=345098&r2=345099&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Oct 23 16:11:30 2018
@@ -9,7 +9,7 @@ struct OSMetaClass;

  struct OSObject {
    virtual void retain();
-  virtual void release();
+  virtual void release() {};
    virtual ~OSObject(){}

    static OSObject *generateObject(int);


_______________________________________________
cfe-commits mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


_______________________________________________
cfe-commits mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
<memcpy.c>


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: r345099 - [analyzer] Trust summaries for OSObject::retain and OSObject::release

Oleg Smolsky via cfe-dev
Hi,

On 11/27/18 12:23 AM, George Karpenkov wrote:

> The error is indeed strange.
> The body is declared as
>
>    LazyDeclStmtPtr Body;
>
> where
>
> using LazyDeclStmtPtr =
>      LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;
>
> where
>
> template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT
> Offset)>
> struct LazyOffsetPtr {
>    mutable uint64_t Ptr = 0;
> (…)
>    explicit operator bool() const { return Ptr != 0; }
> (…)
> }
>
> so it does not seem like it can be uninitialized.
> Sadly on macOS I don’t have either valgrind or msan,
> so I can’t reproduce the failure.
> Do you think you could debug further?
> Is “Body” indeed uninitialized at use time? (e.g. if you print it..)

If I print Body.Ptr when isThisDeclarationADefinition() is called from
RetainSummaryManager::canEval it's 0.

I don't know this code at all but it seems like the

     const FunctionDecl* FDD = FD->getDefinition();

call in RetainSummaryManager::canEval makes isThisDeclarationADefinition
be run two times and Body.Ptr is 0 both times. I've no idea if thes 0s
are by accident or it's indeed by some initialization.

> A stacktrace from a debug build should be helpful.

Stack trace the first time we end up in isThisDeclarationADefinition
form RetainSummaryManager::canEval:

(gdb) where
#0  clang::FunctionDecl::isThisDeclarationADefinition (this=0x654a480)
at ../tools/clang/include/clang/AST/Decl.h:1979
#1  0x0000000000c79dcd in clang::FunctionDecl::isDefined
(this=0x654a480, Definition=@0x7fffffff82c8: 0x47929b <_start>) at
../tools/clang/lib/AST/Decl.cpp:2720
#2  0x0000000000c90299 in clang::FunctionDecl::getDefinition
(this=0x654a480) at ../tools/clang/include/clang/AST/Decl.h:1952
#3  0x000000000220ffe5 in clang::FunctionDecl::getDefinition
(this=0x654a480) at ../tools/clang/include/clang/AST/Decl.h:1957
#4  0x000000000220c8c3 in clang::ento::RetainSummaryManager::canEval
(this=0x6564e10, CE=0x655a580, FD=0x654a480,
hasTrustedImplementationAnnotation=@0x7fffffff8857: false) at
../tools/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp:562
#5  0x0000000001f542d1 in
clang::ento::retaincountchecker::RetainCountChecker::evalCall
(this=0x64d29e0, CE=0x655a580, C=...) at
../tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp:772
#6  0x0000000001f5b240 in
clang::ento::eval::Call::_evalCall<clang::ento::retaincountchecker::RetainCountChecker>
(checker=0x64d29e0, CE=0x655a580, C=...) at
../tools/clang/include/clang/StaticAnalyzer/Core/Checker.h:478
#7  0x0000000002114022 in clang::ento::CheckerFn<bool (clang::CallExpr
const*, clang::ento::CheckerContext&)>::operator()(clang::CallExpr
const*, clang::ento::CheckerContext&) const (this=0x7fffffff8a20,
ps=..., ps=...) at
../tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:70
#8  0x0000000002110c98 in
clang::ento::CheckerManager::runCheckersForEvalCall (this=0x64c57b0,
Dst=..., Src=..., Call=..., Eng=...) at
../tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:662
#9  0x0000000002181729 in clang::ento::ExprEngine::evalCall
(this=0x7fffffffa8d0, Dst=..., Pred=0x656b930, Call=...) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp:569
#10 0x00000000021815ec in clang::ento::ExprEngine::VisitCallExpr
(this=0x7fffffffa8d0, CE=0x655a580, Pred=0x656b930, dst=...) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp:496
#11 0x000000000214b749 in clang::ento::ExprEngine::Visit
(this=0x7fffffffa8d0, S=0x655a580, Pred=0x656b930, DstTop=...) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:1540
#12 0x000000000214818a in clang::ento::ExprEngine::ProcessStmt
(this=0x7fffffffa8d0, currStmt=0x655a580, Pred=0x656b600) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:741
#13 0x0000000002147e49 in clang::ento::ExprEngine::processCFGElement
(this=0x7fffffffa8d0, E=..., Pred=0x656b600, StmtIdx=10,
Ctx=0x7fffffffa398) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:579
#14 0x00000000021326a9 in clang::ento::CoreEngine::HandlePostStmt
(this=0x7fffffffa8f0, B=0x655cc38, StmtIdx=10, Pred=0x656b600) at
../tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:439
#15 0x0000000002131f69 in clang::ento::CoreEngine::dispatchWorkItem
(this=0x7fffffffa8f0, Pred=0x656b600, Loc=..., WU=...) at
../tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:193
#16 0x0000000002131a0e in clang::ento::CoreEngine::ExecuteWorkList
(this=0x7fffffffa8f0, L=0x6563740, Steps=224988, InitState=...) at
../tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:149
#17 0x0000000001aeea98 in clang::ento::ExprEngine::ExecuteWorkList
(this=0x7fffffffa8d0, L=0x6563740, Steps=225000) at
../tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:165
#18 0x0000000001a87fa9 in (anonymous
namespace)::AnalysisConsumer::RunPathSensitiveChecks (this=0x64c20f0,
D=0x655a3a8, IMode=clang::ento::ExprEngine::Inline_Regular,
VisitedCallees=0x7fffffffaf38) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:741
#19 0x0000000001a87905 in (anonymous
namespace)::AnalysisConsumer::HandleCode (this=0x64c20f0, D=0x655a3a8,
Mode=2, IMode=clang::ento::ExprEngine::Inline_Regular,
VisitedCallees=0x7fffffffaf38) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:716
#20 0x0000000001a87496 in (anonymous
namespace)::AnalysisConsumer::HandleDeclsCallGraph (this=0x64c20f0,
LocalTUDeclsSize=53) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:507
#21 0x0000000001a85f2d in (anonymous
namespace)::AnalysisConsumer::runAnalysisOnTranslationUnit
(this=0x64c20f0, C=...) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:554
#22 0x0000000001a85916 in (anonymous
namespace)::AnalysisConsumer::HandleTranslationUnit (this=0x64c20f0,
C=...) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:585
#23 0x0000000002444251 in
clang::MultiplexConsumer::HandleTranslationUnit (this=0x64c2850,
Ctx=...) at ../tools/clang/lib/Frontend/MultiplexConsumer.cpp:287
#24 0x000000000271a44a in clang::ParseAST (S=..., PrintStats=false,
SkipFunctionBodies=false) at ../tools/clang/lib/Parse/ParseAST.cpp:170
#25 0x00000000023fd05e in clang::ASTFrontendAction::ExecuteAction
(this=0x64cc010) at ../tools/clang/lib/Frontend/FrontendAction.cpp:1018
#26 0x00000000023fca90 in clang::FrontendAction::Execute
(this=0x64cc010) at ../tools/clang/lib/Frontend/FrontendAction.cpp:917
#27 0x00000000023759e2 in clang::CompilerInstance::ExecuteAction
(this=0x7fffffffb6b0, Act=...) at
../tools/clang/lib/Frontend/CompilerInstance.cpp:968
#28 0x00000000018aa482 in
clang::tooling::FrontendActionFactory::runInvocation
(this=0x7fffffffc760, Invocation=std::shared_ptr (empty) 0x0,
Files=0x64529a0, PCHContainerOps=..., DiagConsumer=0x7fffffffcb00) at
../tools/clang/lib/Tooling/Tooling.cpp:370
#29 0x000000000116089e in
clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&,
clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::string>,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, bool,
llvm::StringRef)::ActionFactory::runInvocation(std::shared_ptr<clang::CompilerInvocation>,
clang::FileManager*, std::shared_ptr<clang::PCHContainerOperations>,
clang::DiagnosticConsumer*) (this=0x7fffffffc760, Invocation=warning:
RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::CompilerInvocation*,
std::default_delete<clang::CompilerInvocation>, std::allocator<void>,
(__gnu_cxx::_Lock_policy)2>'
warning: RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::CompilerInvocation*,
std::default_delete<clang::CompilerInvocation>, std::allocator<void>,
(__gnu_cxx::_Lock_policy)2>'
std::shared_ptr (count 2, weak 0) 0x644f910, Files=0x64529a0,
PCHContainerOps=warning: RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::PCHContainerOperations*,
std::__shared_ptr<clang::PCHContainerOperations,
(__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocator<clang::PCHContainerOperations>
 >, std::allocator<clang::PCHContainerOperations>,
(__gnu_cxx::_Lock_policy)2>'
warning: RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::PCHContainerOperations*,
std::__shared_ptr<clang::PCHContainerOperations,
(__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocator<clang::PCHContainerOperations>
 >, std::allocator<clang::PCHContainerOperations>,
(__gnu_cxx::_Lock_policy)2>'
std::shared_ptr (count 3, weak 0) 0x644a270,
DiagConsumer=0x7fffffffcb00) at
../tools/clang/tools/extra/clang-tidy/ClangTidy.cpp:572
#30 0x00000000018aa317 in clang::tooling::ToolInvocation::runInvocation
(this=0x7fffffffc288, BinaryName=0x6440088 "clang-tool",
Compilation=0x644eb80, Invocation=std::shared_ptr (empty) 0x0,
PCHContainerOps=std::shared_ptr (empty) 0x0) at
../tools/clang/lib/Tooling/Tooling.cpp:345
#31 0x00000000018a8a59 in clang::tooling::ToolInvocation::run
(this=0x7fffffffc288) at ../tools/clang/lib/Tooling/Tooling.cpp:330
#32 0x00000000018ab924 in clang::tooling::ClangTool::run
(this=0x7fffffffcc10, Action=0x7fffffffc760) at
../tools/clang/lib/Tooling/Tooling.cpp:519
#33 0x000000000115d517 in clang::tidy::runClangTidy (Context=...,
Compilations=..., InputFiles=llvm::ArrayRef of length 1 = {...},
BaseFS=..., EnableCheckProfile=false, StoreCheckProfile="") at
../tools/clang/tools/extra/clang-tidy/ClangTidy.cpp:593
#34 0x000000000047a29f in clang::tidy::clangTidyMain (argc=3,
argv=0x7fffffffda98) at
../tools/clang/tools/extra/clang-tidy/tool/ClangTidyMain.cpp:428
#35 0x00000000004796c2 in main (argc=5, argv=0x7fffffffda98) at
../tools/clang/tools/extra/clang-tidy/tool/ClangTidyMain.cpp:581

And the second time:

(gdb) where
#0  clang::FunctionDecl::isThisDeclarationADefinition (this=0x654a2b0)
at ../tools/clang/include/clang/AST/Decl.h:1979
#1  0x0000000000c79dcd in clang::FunctionDecl::isDefined
(this=0x654a480, Definition=@0x7fffffff82c8: 0x47929b <_start>) at
../tools/clang/lib/AST/Decl.cpp:2720
#2  0x0000000000c90299 in clang::FunctionDecl::getDefinition
(this=0x654a480) at ../tools/clang/include/clang/AST/Decl.h:1952
#3  0x000000000220ffe5 in clang::FunctionDecl::getDefinition
(this=0x654a480) at ../tools/clang/include/clang/AST/Decl.h:1957
#4  0x000000000220c8c3 in clang::ento::RetainSummaryManager::canEval
(this=0x6564e10, CE=0x655a580, FD=0x654a480,
hasTrustedImplementationAnnotation=@0x7fffffff8857: false) at
../tools/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp:562
#5  0x0000000001f542d1 in
clang::ento::retaincountchecker::RetainCountChecker::evalCall
(this=0x64d29e0, CE=0x655a580, C=...) at
../tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp:772
#6  0x0000000001f5b240 in
clang::ento::eval::Call::_evalCall<clang::ento::retaincountchecker::RetainCountChecker>
(checker=0x64d29e0, CE=0x655a580, C=...) at
../tools/clang/include/clang/StaticAnalyzer/Core/Checker.h:478
#7  0x0000000002114022 in clang::ento::CheckerFn<bool (clang::CallExpr
const*, clang::ento::CheckerContext&)>::operator()(clang::CallExpr
const*, clang::ento::CheckerContext&) const (this=0x7fffffff8a20,
ps=..., ps=...) at
../tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:70
#8  0x0000000002110c98 in
clang::ento::CheckerManager::runCheckersForEvalCall (this=0x64c57b0,
Dst=..., Src=..., Call=..., Eng=...) at
../tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:662
#9  0x0000000002181729 in clang::ento::ExprEngine::evalCall
(this=0x7fffffffa8d0, Dst=..., Pred=0x656b930, Call=...) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp:569
#10 0x00000000021815ec in clang::ento::ExprEngine::VisitCallExpr
(this=0x7fffffffa8d0, CE=0x655a580, Pred=0x656b930, dst=...) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp:496
#11 0x000000000214b749 in clang::ento::ExprEngine::Visit
(this=0x7fffffffa8d0, S=0x655a580, Pred=0x656b930, DstTop=...) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:1540
#12 0x000000000214818a in clang::ento::ExprEngine::ProcessStmt
(this=0x7fffffffa8d0, currStmt=0x655a580, Pred=0x656b600) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:741
#13 0x0000000002147e49 in clang::ento::ExprEngine::processCFGElement
(this=0x7fffffffa8d0, E=..., Pred=0x656b600, StmtIdx=10,
Ctx=0x7fffffffa398) at
../tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:579
#14 0x00000000021326a9 in clang::ento::CoreEngine::HandlePostStmt
(this=0x7fffffffa8f0, B=0x655cc38, StmtIdx=10, Pred=0x656b600) at
../tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:439
#15 0x0000000002131f69 in clang::ento::CoreEngine::dispatchWorkItem
(this=0x7fffffffa8f0, Pred=0x656b600, Loc=..., WU=...) at
../tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:193
#16 0x0000000002131a0e in clang::ento::CoreEngine::ExecuteWorkList
(this=0x7fffffffa8f0, L=0x6563740, Steps=224988, InitState=...) at
../tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:149
#17 0x0000000001aeea98 in clang::ento::ExprEngine::ExecuteWorkList
(this=0x7fffffffa8d0, L=0x6563740, Steps=225000) at
../tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:165
#18 0x0000000001a87fa9 in (anonymous
namespace)::AnalysisConsumer::RunPathSensitiveChecks (this=0x64c20f0,
D=0x655a3a8, IMode=clang::ento::ExprEngine::Inline_Regular,
VisitedCallees=0x7fffffffaf38) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:741
#19 0x0000000001a87905 in (anonymous
namespace)::AnalysisConsumer::HandleCode (this=0x64c20f0, D=0x655a3a8,
Mode=2, IMode=clang::ento::ExprEngine::Inline_Regular,
VisitedCallees=0x7fffffffaf38) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:716
#20 0x0000000001a87496 in (anonymous
namespace)::AnalysisConsumer::HandleDeclsCallGraph (this=0x64c20f0,
LocalTUDeclsSize=53) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:507
#21 0x0000000001a85f2d in (anonymous
namespace)::AnalysisConsumer::runAnalysisOnTranslationUnit
(this=0x64c20f0, C=...) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:554
#22 0x0000000001a85916 in (anonymous
namespace)::AnalysisConsumer::HandleTranslationUnit (this=0x64c20f0,
C=...) at
../tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:585
#23 0x0000000002444251 in
clang::MultiplexConsumer::HandleTranslationUnit (this=0x64c2850,
Ctx=...) at ../tools/clang/lib/Frontend/MultiplexConsumer.cpp:287
#24 0x000000000271a44a in clang::ParseAST (S=..., PrintStats=false,
SkipFunctionBodies=false) at ../tools/clang/lib/Parse/ParseAST.cpp:170
#25 0x00000000023fd05e in clang::ASTFrontendAction::ExecuteAction
(this=0x64cc010) at ../tools/clang/lib/Frontend/FrontendAction.cpp:1018
#26 0x00000000023fca90 in clang::FrontendAction::Execute
(this=0x64cc010) at ../tools/clang/lib/Frontend/FrontendAction.cpp:917
#27 0x00000000023759e2 in clang::CompilerInstance::ExecuteAction
(this=0x7fffffffb6b0, Act=...) at
../tools/clang/lib/Frontend/CompilerInstance.cpp:968
#28 0x00000000018aa482 in
clang::tooling::FrontendActionFactory::runInvocation
(this=0x7fffffffc760, Invocation=std::shared_ptr (empty) 0x0,
Files=0x64529a0, PCHContainerOps=..., DiagConsumer=0x7fffffffcb00) at
../tools/clang/lib/Tooling/Tooling.cpp:370
#29 0x000000000116089e in
clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&,
clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::string>,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, bool,
llvm::StringRef)::ActionFactory::runInvocation(std::shared_ptr<clang::CompilerInvocation>,
clang::FileManager*, std::shared_ptr<clang::PCHContainerOperations>,
clang::DiagnosticConsumer*) (this=0x7fffffffc760, Invocation=warning:
RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::CompilerInvocation*,
std::default_delete<clang::CompilerInvocation>, std::allocator<void>,
(__gnu_cxx::_Lock_policy)2>'
warning: RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::CompilerInvocation*,
std::default_delete<clang::CompilerInvocation>, std::allocator<void>,
(__gnu_cxx::_Lock_policy)2>'
std::shared_ptr (count 2, weak 0) 0x644f910, Files=0x64529a0,
PCHContainerOps=warning: RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::PCHContainerOperations*,
std::__shared_ptr<clang::PCHContainerOperations,
(__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocator<clang::PCHContainerOperations>
 >, std::allocator<clang::PCHContainerOperations>,
(__gnu_cxx::_Lock_policy)2>'
warning: RTTI symbol not found for class
'std::_Sp_counted_deleter<clang::PCHContainerOperations*,
std::__shared_ptr<clang::PCHContainerOperations,
(__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocator<clang::PCHContainerOperations>
 >, std::allocator<clang::PCHContainerOperations>,
(__gnu_cxx::_Lock_policy)2>'
std::shared_ptr (count 3, weak 0) 0x644a270,
DiagConsumer=0x7fffffffcb00) at
../tools/clang/tools/extra/clang-tidy/ClangTidy.cpp:572
#30 0x00000000018aa317 in clang::tooling::ToolInvocation::runInvocation
(this=0x7fffffffc288, BinaryName=0x6440088 "clang-tool",
Compilation=0x644eb80, Invocation=std::shared_ptr (empty) 0x0,
PCHContainerOps=std::shared_ptr (empty) 0x0) at
../tools/clang/lib/Tooling/Tooling.cpp:345
#31 0x00000000018a8a59 in clang::tooling::ToolInvocation::run
(this=0x7fffffffc288) at ../tools/clang/lib/Tooling/Tooling.cpp:330
#32 0x00000000018ab924 in clang::tooling::ClangTool::run
(this=0x7fffffffcc10, Action=0x7fffffffc760) at
../tools/clang/lib/Tooling/Tooling.cpp:519
#33 0x000000000115d517 in clang::tidy::runClangTidy (Context=...,
Compilations=..., InputFiles=llvm::ArrayRef of length 1 = {...},
BaseFS=..., EnableCheckProfile=false, StoreCheckProfile="") at
../tools/clang/tools/extra/clang-tidy/ClangTidy.cpp:593
#34 0x000000000047a29f in clang::tidy::clangTidyMain (argc=3,
argv=0x7fffffffda98) at
../tools/clang/tools/extra/clang-tidy/tool/ClangTidyMain.cpp:428
#35 0x00000000004796c2 in main (argc=5, argv=0x7fffffffda98) at
../tools/clang/tools/extra/clang-tidy/tool/ClangTidyMain.cpp:581

/Mikael

>
> Thanks,
> George
>
>> On Nov 26, 2018, at 12:03 AM, Mikael Holmén
>> <[hidden email] <mailto:[hidden email]>> wrote:
>>
>> Hi again,
>>
>> Do you have any opinion about the below valgrind complaint that starts
>> appearing with this patch?
>>
>> valgrind still complains on it on current trunk.
>>
>> I see it when compiling with clang 3.6.0. I've also tried gcc 5.4.0 but
>> then I don't get it.
>>
>> Regards,
>> Mikael
>>
>> On 11/21/18 8:33 AM, Mikael Holmén via cfe-commits wrote:
>>> Hi George,
>>>
>>> I noticed that valgrind started complaining in one case with this patch.
>>>
>>> I've no idea if it's really due to something in the patch or if it's
>>> something old that surfaced or if it's a false flag.
>>>
>>> Anyway, with this patch the following
>>>
>>>   valgrind clang-tidy -checks='-*,clang-analyzer-*' 'memcpy.c' -- -O0
>>>
>>> gives me
>>>
>>> ==18829== Memcheck, a memory error detector
>>> ==18829== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
>>> ==18829== Using Valgrind-3.10.1 and LibVEX; rerun with -h for
>>> copyright info
>>> ==18829== Command: build-all/bin/clang-tidy -checks=-*,clang-analyzer-*
>>> memcpy.c -- -O0
>>> ==18829==
>>> ==18829== Conditional jump or move depends on uninitialised value(s)
>>> ==18829==    at 0xE580DF:
>>> clang::ento::RetainSummaryManager::canEval(clang::CallExpr const*,
>>> clang::FunctionDecl const*, bool&) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xD034AA:
>>> clang::ento::retaincountchecker::RetainCountChecker::evalCall(clang::CallExpr
>>> const*, clang::ento::CheckerContext&) const (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xDCBCD7:
>>> clang::ento::CheckerManager::runCheckersForEvalCall(clang::ento::ExplodedNodeSet&,
>>> clang::ento::ExplodedNodeSet const&, clang::ento::CallEvent const&,
>>> clang::ento::ExprEngine&) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xE033D5:
>>> clang::ento::ExprEngine::evalCall(clang::ento::ExplodedNodeSet&,
>>> clang::ento::ExplodedNode*, clang::ento::CallEvent const&) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xE03165:
>>> clang::ento::ExprEngine::VisitCallExpr(clang::CallExpr const*,
>>> clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xDE3D9A: clang::ento::ExprEngine::Visit(clang::Stmt
>>> const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xDDEFD1:
>>> clang::ento::ExprEngine::ProcessStmt(clang::Stmt const*,
>>> clang::ento::ExplodedNode*) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xDDEBBC:
>>> clang::ento::ExprEngine::processCFGElement(clang::CFGElement,
>>> clang::ento::ExplodedNode*, unsigned int,
>>> clang::ento::NodeBuilderContext*) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xDD3154:
>>> clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned
>>> int, clang::ento::ExplodedNode*) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xDD24D3:
>>> clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*,
>>> unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>)
>>> (in /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xB8E90E: (anonymous
>>> namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int,
>>> clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl
>>> const*, llvm::DenseMapInfo<clang::Decl const*> >*) (in
>>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==    by 0xB89943: (anonymous
>>> namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&)
>>> (in /data/repo/llvm-patch/build-all/bin/clang-tidy)
>>> ==18829==
>>>
>>> The call to
>>>
>>>      const FunctionDecl* FDD = FD->getDefinition();
>>>
>>> in RetainSummaryManager::canEval eventually ends up in
>>>
>>>    bool isThisDeclarationADefinition() const {
>>>      return isDeletedAsWritten() || isDefaulted() || Body ||
>>> hasSkippedBody() ||
>>>             isLateTemplateParsed() || willHaveBody() ||
>>> hasDefiningAttr();
>>>    }
>>>
>>> And here it seems to be the access of "Body" that valgrind complains on.
>>> If I simply comment out "Body" the complaint is gone.
>>>
>>> I really have no clue about this code, but perhaps this makes some sense
>>> to you? Or perhaps to someone else?
>>>
>>> Regards,
>>> Mikael
>>>
>>> On 10/24/18 1:11 AM, George Karpenkov via cfe-commits wrote:
>>>> Author: george.karpenkov
>>>> Date: Tue Oct 23 16:11:30 2018
>>>> New Revision: 345099
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=345099&view=rev
>>>> Log:
>>>> [analyzer] Trust summaries for OSObject::retain and OSObject::release
>>>>
>>>> Refactor the way in which summaries are consumed for safeMetaCast
>>>>
>>>> Differential Revision: https://reviews.llvm.org/D53549
>>>>
>>>> Modified:
>>>>      cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
>>>>      cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
>>>>      cfe/trunk/test/Analysis/osobject-retain-release.cpp
>>>>
>>>> Modified:
>>>> cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345099&r1=345098&r2=345099&view=diff
>>>> ==============================================================================
>>>> ---
>>>> cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
>>>> (original)
>>>> +++
>>>> cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
>>>> Tue Oct 23 16:11:30 2018
>>>> @@ -776,31 +776,27 @@ bool RetainCountChecker::evalCall(const
>>>>
>>>>     const LocationContext *LCtx = C.getLocationContext();
>>>>
>>>> -  // Process OSDynamicCast: should just return the first argument.
>>>> -  // For now, tresting the cast as a no-op, and disregarding the
>>>> case where
>>>> -  // the output becomes null due to the type mismatch.
>>>> -  if (FD->getNameAsString() == "safeMetaCast") {
>>>> -    state = state->BindExpr(CE, LCtx,
>>>> -                            state->getSVal(CE->getArg(0), LCtx));
>>>> -    C.addTransition(state);
>>>> -    return true;
>>>> -  }
>>>> -
>>>>     // See if it's one of the specific functions we know how to eval.
>>>>     if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
>>>>       return false;
>>>>
>>>>     // Bind the return value.
>>>> -  SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
>>>> -  if (RetVal.isUnknown() ||
>>>> -      (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
>>>> +  // For now, all the functions which we can evaluate and which take
>>>> +  // at least one argument are identities.
>>>> +  if (CE->getNumArgs() >= 1) {
>>>> +    SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
>>>> +
>>>>       // If the receiver is unknown or the function has
>>>>       // 'rc_ownership_trusted_implementation' annotate attribute,
>>>> conjure a
>>>>       // return value.
>>>> -    SValBuilder &SVB = C.getSValBuilder();
>>>> -    RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy,
>>>> C.blockCount());
>>>> +    if (RetVal.isUnknown() ||
>>>> +        (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
>>>> +      SValBuilder &SVB = C.getSValBuilder();
>>>> +      RetVal =
>>>> +          SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy,
>>>> C.blockCount());
>>>> +    }
>>>> +    state = state->BindExpr(CE, LCtx, RetVal, false);
>>>>     }
>>>> -  state = state->BindExpr(CE, LCtx, RetVal, false);
>>>>
>>>>     C.addTransition(state);
>>>>     return true;
>>>>
>>>> Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345099&r1=345098&r2=345099&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
>>>> (original)
>>>> +++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue
>>>> Oct 23 16:11:30 2018
>>>> @@ -102,9 +102,6 @@ RetainSummaryManager::generateSummary(co
>>>>       return getPersistentStopSummary();
>>>>     }
>>>>
>>>> -  // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs
>>>> on the
>>>> -  // function's type.
>>>> -  const FunctionType *FT = FD->getType()->getAs<FunctionType>();
>>>>     const IdentifierInfo *II = FD->getIdentifier();
>>>>     if (!II)
>>>>       return getDefaultSummary();
>>>> @@ -115,7 +112,8 @@ RetainSummaryManager::generateSummary(co
>>>>     // down below.
>>>>     FName = FName.substr(FName.find_first_not_of('_'));
>>>>
>>>> -  // Inspect the result type.
>>>> +  // Inspect the result type. Strip away any typedefs.
>>>> +  const auto *FT = FD->getType()->getAs<FunctionType>();
>>>>     QualType RetTy = FT->getReturnType();
>>>>     std::string RetTyName = RetTy.getAsString();
>>>>
>>>> @@ -506,12 +504,6 @@ bool RetainSummaryManager::isTrustedRefe
>>>>   bool RetainSummaryManager::canEval(const CallExpr *CE,
>>>>                                      const FunctionDecl *FD,
>>>>                                      bool
>>>> &hasTrustedImplementationAnnotation) {
>>>> -  // For now, we're only handling the functions that return aliases
>>>> of their
>>>> -  // arguments: CFRetain (and its families).
>>>> -  // Eventually we should add other functions we can model entirely,
>>>> -  // such as CFRelease, which don't invalidate their arguments or
>>>> globals.
>>>> -  if (CE->getNumArgs() != 1)
>>>> -    return false;
>>>>
>>>>     IdentifierInfo *II = FD->getIdentifier();
>>>>     if (!II)
>>>> @@ -533,6 +525,13 @@ bool RetainSummaryManager::canEval(const
>>>>         return isRetain(FD, FName) || isAutorelease(FD, FName) ||
>>>>                isMakeCollectable(FName);
>>>>
>>>> +    // Process OSDynamicCast: should just return the first argument.
>>>> +    // For now, treating the cast as a no-op, and disregarding the
>>>> case where
>>>> +    // the output becomes null due to the type mismatch.
>>>> +    if (TrackOSObjects && FName == "safeMetaCast") {
>>>> +      return true;
>>>> +    }
>>>> +
>>>>       const FunctionDecl* FDD = FD->getDefinition();
>>>>       if (FDD && isTrustedReferenceCountImplementation(FDD)) {
>>>>         hasTrustedImplementationAnnotation = true;
>>>> @@ -540,6 +539,12 @@ bool RetainSummaryManager::canEval(const
>>>>       }
>>>>     }
>>>>
>>>> +  if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
>>>> +    const CXXRecordDecl *Parent = MD->getParent();
>>>> +    if (TrackOSObjects && Parent && isOSObjectSubclass(Parent))
>>>> +      return FName == "release" || FName == "retain";
>>>> +  }
>>>> +
>>>>     return false;
>>>>
>>>>   }
>>>>
>>>> Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345099&r1=345098&r2=345099&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
>>>> +++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Oct 23
>>>> 16:11:30 2018
>>>> @@ -9,7 +9,7 @@ struct OSMetaClass;
>>>>
>>>>   struct OSObject {
>>>>     virtual void retain();
>>>> -  virtual void release();
>>>> +  virtual void release() {};
>>>>     virtual ~OSObject(){}
>>>>
>>>>     static OSObject *generateObject(int);
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> [hidden email] <mailto:[hidden email]>
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> [hidden email] <mailto:[hidden email]>
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>> <memcpy.c>
>

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev