diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/CallEvent.cpp')
| -rw-r--r-- | lib/StaticAnalyzer/Core/CallEvent.cpp | 37 | 
1 files changed, 25 insertions, 12 deletions
| diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index 0e7f31502e81..a5f7500e6307 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -1,9 +1,8 @@  //===- CallEvent.cpp - Wrapper for all function and method calls ----------===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception  //  //===----------------------------------------------------------------------===//  // @@ -357,20 +356,32 @@ bool CallEvent::isCalled(const CallDescription &CD) const {    // FIXME: Add ObjC Message support.    if (getKind() == CE_ObjCMessage)      return false; + +  const IdentifierInfo *II = getCalleeIdentifier(); +  if (!II) +    return false; +  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(getDecl()); +  if (!FD) +    return false; + +  if (CD.Flags & CDF_MaybeBuiltin) { +    return CheckerContext::isCLibraryFunction(FD, CD.getFunctionName()) && +           (!CD.RequiredArgs || CD.RequiredArgs <= getNumArgs()); +  } +    if (!CD.IsLookupDone) {      CD.IsLookupDone = true;      CD.II = &getState()->getStateManager().getContext().Idents.get(          CD.getFunctionName());    } -  const IdentifierInfo *II = getCalleeIdentifier(); -  if (!II || II != CD.II) + +  if (II != CD.II)      return false; -  const Decl *D = getDecl();    // If CallDescription provides prefix names, use them to improve matching    // accuracy. -  if (CD.QualifiedName.size() > 1 && D) { -    const DeclContext *Ctx = D->getDeclContext(); +  if (CD.QualifiedName.size() > 1 && FD) { +    const DeclContext *Ctx = FD->getDeclContext();      // See if we'll be able to match them all.      size_t NumUnmatched = CD.QualifiedName.size() - 1;      for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) { @@ -394,8 +405,7 @@ bool CallEvent::isCalled(const CallDescription &CD) const {        return false;    } -  return (CD.RequiredArgs == CallDescription::NoArgRequirement || -          CD.RequiredArgs == getNumArgs()); +  return (!CD.RequiredArgs || CD.RequiredArgs == getNumArgs());  }  SVal CallEvent::getArgSVal(unsigned Index) const { @@ -756,8 +766,11 @@ RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {    // Does the decl that we found have an implementation?    const FunctionDecl *Definition; -  if (!Result->hasBody(Definition)) +  if (!Result->hasBody(Definition)) { +    if (!DynType.canBeASubClass()) +      return AnyFunctionCall::getRuntimeDefinition();      return {}; +  }    // We found a definition. If we're not sure that this devirtualization is    // actually what will happen at runtime, make sure to provide the region so | 
