Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Analysis/ObjCNoReturn.cpp
Line
Count
Source
1
//= ObjCNoReturn.cpp - Handling of Cocoa APIs known not to return --*- C++ -*---
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements special handling of recognizing ObjC API hooks that
10
// do not return but aren't marked as such in API headers.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/ASTContext.h"
15
#include "clang/AST/ExprObjC.h"
16
#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
17
18
using namespace clang;
19
20
3.09k
static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) {
21
3.09k
  if (!Class)
22
1.01k
    return false;
23
2.08k
  if (Class->getIdentifier() == II)
24
10
    return true;
25
2.07k
  return isSubclass(Class->getSuperClass(), II);
26
2.08k
}
27
28
ObjCNoReturn::ObjCNoReturn(ASTContext &C)
29
  : RaiseSel(GetNullarySelector("raise", C)),
30
    NSExceptionII(&C.Idents.get("NSException"))
31
26.6k
{
32
  // Generate selectors.
33
26.6k
  SmallVector<IdentifierInfo*, 3> II;
34
35
  // raise:format:
36
26.6k
  II.push_back(&C.Idents.get("raise"));
37
26.6k
  II.push_back(&C.Idents.get("format"));
38
26.6k
  NSExceptionInstanceRaiseSelectors[0] =
39
26.6k
    C.Selectors.getSelector(II.size(), &II[0]);
40
41
  // raise:format:arguments:
42
26.6k
  II.push_back(&C.Idents.get("arguments"));
43
26.6k
  NSExceptionInstanceRaiseSelectors[1] =
44
26.6k
    C.Selectors.getSelector(II.size(), &II[0]);
45
26.6k
}
46
47
48
4.09k
bool ObjCNoReturn::isImplicitNoReturn(const ObjCMessageExpr *ME) {
49
4.09k
  Selector S = ME->getSelector();
50
51
4.09k
  if (ME->isInstanceMessage()) {
52
    // Check for the "raise" message.
53
3.06k
    return S == RaiseSel;
54
3.06k
  }
55
56
1.02k
  if (const ObjCInterfaceDecl *ID = ME->getReceiverInterface()) {
57
1.02k
    if (isSubclass(ID, NSExceptionII) &&
58
1.02k
        
llvm::is_contained(NSExceptionInstanceRaiseSelectors, S)10
)
59
7
      return true;
60
1.02k
  }
61
62
1.01k
  return false;
63
1.02k
}