Coverage Report

Created: 2020-02-25 14:32

/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
2.96k
static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) {
21
2.96k
  if (!Class)
22
974
    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
21.1k
{
32
21.1k
  // Generate selectors.
33
21.1k
  SmallVector<IdentifierInfo*, 3> II;
34
21.1k
35
21.1k
  // raise:format:
36
21.1k
  II.push_back(&C.Idents.get("raise"));
37
21.1k
  II.push_back(&C.Idents.get("format"));
38
21.1k
  NSExceptionInstanceRaiseSelectors[0] =
39
21.1k
    C.Selectors.getSelector(II.size(), &II[0]);
40
21.1k
41
21.1k
  // raise:format:arguments:
42
21.1k
  II.push_back(&C.Idents.get("arguments"));
43
21.1k
  NSExceptionInstanceRaiseSelectors[1] =
44
21.1k
    C.Selectors.getSelector(II.size(), &II[0]);
45
21.1k
}
46
47
48
3.95k
bool ObjCNoReturn::isImplicitNoReturn(const ObjCMessageExpr *ME) {
49
3.95k
  Selector S = ME->getSelector();
50
3.95k
51
3.95k
  if (ME->isInstanceMessage()) {
52
2.96k
    // Check for the "raise" message.
53
2.96k
    return S == RaiseSel;
54
2.96k
  }
55
984
56
984
  if (const ObjCInterfaceDecl *ID = ME->getReceiverInterface()) {
57
984
    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
984
  }
64
984
65
984
  
return false977
;
66
984
}