Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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
2.96k
static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) {
21
2.96k
  if (!Class)
22
972
    return false;
23
1.99k
  if (Class->getIdentifier() == II)
24
10
    return true;
25
1.98k
  return isSubclass(Class->getSuperClass(), II);
26
1.98k
}
27
28
ObjCNoReturn::ObjCNoReturn(ASTContext &C)
29
  : RaiseSel(GetNullarySelector("raise", C)),
30
    NSExceptionII(&C.Idents.get("NSException"))
31
776k
{
32
776k
  // Generate selectors.
33
776k
  SmallVector<IdentifierInfo*, 3> II;
34
776k
35
776k
  // raise:format:
36
776k
  II.push_back(&C.Idents.get("raise"));
37
776k
  II.push_back(&C.Idents.get("format"));
38
776k
  NSExceptionInstanceRaiseSelectors[0] =
39
776k
    C.Selectors.getSelector(II.size(), &II[0]);
40
776k
41
776k
  // raise:format:arguments:
42
776k
  II.push_back(&C.Idents.get("arguments"));
43
776k
  NSExceptionInstanceRaiseSelectors[1] =
44
776k
    C.Selectors.getSelector(II.size(), &II[0]);
45
776k
}
46
47
48
3.89k
bool ObjCNoReturn::isImplicitNoReturn(const ObjCMessageExpr *ME) {
49
3.89k
  Selector S = ME->getSelector();
50
3.89k
51
3.89k
  if (ME->isInstanceMessage()) {
52
2.91k
    // Check for the "raise" message.
53
2.91k
    return S == RaiseSel;
54
2.91k
  }
55
982
56
982
  if (const ObjCInterfaceDecl *ID = ME->getReceiverInterface()) {
57
982
    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
982
  }
64
982
65
982
  
return false975
;
66
982
}