~ubuntu-branches/ubuntu/trusty/llvm-toolchain-snapshot/trusty-201310232150

« back to all changes in this revision

Viewing changes to clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-27 15:01:57 UTC
  • mfrom: (0.10.1) (0.9.1) (0.8.1) (0.7.1) (0.6.1) (0.5.2)
  • Revision ID: package-import@ubuntu.com-20130527150157-tdkrsjpuvht7v0qx
Tags: 1:3.4~svn182733-1~exp1
* New snapshot release (3.4 release)
* Add a symlink of libLLVM-3.4.so.1 to usr/lib/llvm-3.4/lib/libLLVM-3.4.so
    to fix make the llvm-config-3.4 --libdir work (Closes: #708677)
  * Various packages rename to allow co installations:
    * libclang1 => libclang1-3.4
    * libclang1-dbg => libclang1-3.4-dbg
    * libclang-dev => libclang-3.4-dev
    * libclang-common-dev => libclang-common-3.4-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
676
676
  return CIP_Allowed;
677
677
}
678
678
 
679
 
/// Returns true if the given C++ class is a container.
 
679
/// Returns true if the given C++ class contains a member with the given name.
 
680
static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD,
 
681
                      StringRef Name) {
 
682
  const IdentifierInfo &II = Ctx.Idents.get(Name);
 
683
  DeclarationName DeclName = Ctx.DeclarationNames.getIdentifier(&II);
 
684
  if (!RD->lookup(DeclName).empty())
 
685
    return true;
 
686
 
 
687
  CXXBasePaths Paths(false, false, false);
 
688
  if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember,
 
689
                        DeclName.getAsOpaquePtr(),
 
690
                        Paths))
 
691
    return true;
 
692
 
 
693
  return false;
 
694
}
 
695
 
 
696
/// Returns true if the given C++ class is a container or iterator.
680
697
///
681
698
/// Our heuristic for this is whether it contains a method named 'begin()' or a
682
 
/// nested type named 'iterator'.
 
699
/// nested type named 'iterator' or 'iterator_category'.
683
700
static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) {
684
 
  // Don't record any path information.
685
 
  CXXBasePaths Paths(false, false, false);
686
 
 
687
 
  const IdentifierInfo &BeginII = Ctx.Idents.get("begin");
688
 
  DeclarationName BeginName = Ctx.DeclarationNames.getIdentifier(&BeginII);
689
 
  DeclContext::lookup_const_result BeginDecls = RD->lookup(BeginName);
690
 
  if (!BeginDecls.empty())
691
 
    return true;
692
 
  if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember,
693
 
                        BeginName.getAsOpaquePtr(),
694
 
                        Paths))
695
 
    return true;
696
 
  
697
 
  const IdentifierInfo &IterII = Ctx.Idents.get("iterator");
698
 
  DeclarationName IteratorName = Ctx.DeclarationNames.getIdentifier(&IterII);
699
 
  DeclContext::lookup_const_result IterDecls = RD->lookup(IteratorName);
700
 
  if (!IterDecls.empty())
701
 
    return true;
702
 
  if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember,
703
 
                        IteratorName.getAsOpaquePtr(),
704
 
                        Paths))
705
 
    return true;
706
 
 
707
 
  return false;
 
701
  return hasMember(Ctx, RD, "begin") ||
 
702
         hasMember(Ctx, RD, "iterator") ||
 
703
         hasMember(Ctx, RD, "iterator_category");
708
704
}
709
705
 
710
706
/// Returns true if the given function refers to a constructor or destructor of
711
 
/// a C++ container.
 
707
/// a C++ container or iterator.
712
708
///
713
709
/// We generally do a poor job modeling most containers right now, and would
714
 
/// prefer not to inline their methods.
 
710
/// prefer not to inline their setup and teardown.
715
711
static bool isContainerCtorOrDtor(const ASTContext &Ctx,
716
712
                                  const FunctionDecl *FD) {
717
 
  // Heuristic: a type is a container if it contains a "begin()" method
718
 
  // or a type named "iterator".
719
713
  if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD)))
720
714
    return false;
721
715
 
723
717
  return isContainerClass(Ctx, RD);
724
718
}
725
719
 
 
720
/// Returns true if the given function is the destructor of a class named
 
721
/// "shared_ptr".
 
722
static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
 
723
  const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(FD);
 
724
  if (!Dtor)
 
725
    return false;
 
726
 
 
727
  const CXXRecordDecl *RD = Dtor->getParent();
 
728
  if (const IdentifierInfo *II = RD->getDeclName().getAsIdentifierInfo())
 
729
    if (II->isStr("shared_ptr"))
 
730
        return true;
 
731
 
 
732
  return false;
 
733
}
 
734
 
726
735
/// Returns true if the function in \p CalleeADC may be inlined in general.
727
736
///
728
737
/// This checks static properties of the function, such as its signature and
755
764
        if (!Ctx.getSourceManager().isFromMainFile(FD->getLocation()))
756
765
          if (isContainerCtorOrDtor(Ctx, FD))
757
766
            return false;
 
767
            
 
768
      // Conditionally control the inlining of the destructor of C++ shared_ptr.
 
769
      // We don't currently do a good job modeling shared_ptr because we can't
 
770
      // see the reference count, so treating as opaque is probably the best
 
771
      // idea.
 
772
      if (!Opts.mayInlineCXXSharedPtrDtor())
 
773
        if (isCXXSharedPtrDtor(FD))
 
774
          return false;
 
775
 
758
776
    }
759
777
  }
760
778