Coverage Report

Created: 2020-09-19 12:23

/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.03k
static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) {
21
3.03k
  if (!Class)
22
996
    return false;
23
2.04k
  if (Class->getIdentifier() == II)
24
10
    return true;
25
2.03k
  return isSubclass(Class->getSuperClass(), II);
26
2.03k
}
27
28
ObjCNoReturn::ObjCNoReturn(ASTContext &C)
29
  : RaiseSel(GetNullarySelector("raise", C)),
30
    NSExceptionII(&C.Idents.get("NSException"))
31
24.3k
{
32
  // Generate selectors.
33
24.3k
  SmallVector<IdentifierInfo*, 3> II;
34
24.3k
35
  // raise:format:
36
24.3k
  II.push_back(&C.Idents.get("raise"));
37
24.3k
  II.push_back(&C.Idents.get("format"));
38
24.3k
  NSExceptionInstanceRaiseSelectors[0] =
39
24.3k
    C.Selectors.getSelector(II.size(), &II[0]);
40
24.3k
41
  // raise:format:arguments:
42
24.3k
  II.push_back(&C.Idents.get("arguments"));
43
24.3k
  NSExceptionInstanceRaiseSelectors[1] =
44
24.3k
    C.Selectors.getSelector(II.size(), &II[0]);
45
24.3k
}
46
47
48
4.00k
bool ObjCNoReturn::isImplicitNoReturn(const ObjCMessageExpr *ME) {
49
4.00k
  Selector S = ME->getSelector();
50
4.00k
51
4.00k
  if (ME->isInstanceMessage()) {
52
    // Check for the "raise" message.
53
3.00k
    return S == RaiseSel;
54
3.00k
  }
55
1.00k
56
1.00k
  if (const ObjCInterfaceDecl *ID = ME->getReceiverInterface()) {
57
1.00k
    if (isSubclass(ID, NSExceptionII)) {
58
19
      for (unsigned i = 0; i < NUM_RAISE_SELECTORS; 
++i9
) {
59
16
        if (S == NSExceptionInstanceRaiseSelectors[i])
60
7
          return true;
61
16
      }
62
10
    }
63
1.00k
  }
64
1.00k
65
999
  return false;
66
1.00k
}