Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
Line
Count
Source (jump to first uncovered line)
1
//===---- CheckerHelpers.cpp - Helper functions for checkers ----*- 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 defines several static functions for use in checkers.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
14
#include "clang/AST/Decl.h"
15
#include "clang/AST/Expr.h"
16
17
namespace clang {
18
19
namespace ento {
20
21
// Recursively find any substatements containing macros
22
44
bool containsMacro(const Stmt *S) {
23
44
  if (S->getBeginLoc().isMacroID())
24
2
    return true;
25
42
26
42
  if (S->getEndLoc().isMacroID())
27
0
    return true;
28
42
29
42
  for (const Stmt *Child : S->children())
30
31
    if (Child && containsMacro(Child))
31
0
      return true;
32
42
33
42
  return false;
34
42
}
35
36
// Recursively find any substatements containing enum constants
37
42
bool containsEnum(const Stmt *S) {
38
42
  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
39
42
40
42
  if (DR && 
isa<EnumConstantDecl>(DR->getDecl())10
)
41
0
    return true;
42
42
43
42
  for (const Stmt *Child : S->children())
44
31
    if (Child && containsEnum(Child))
45
0
      return true;
46
42
47
42
  return false;
48
42
}
49
50
// Recursively find any substatements containing static vars
51
42
bool containsStaticLocal(const Stmt *S) {
52
42
  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
53
42
54
42
  if (DR)
55
10
    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
56
10
      if (VD->isStaticLocal())
57
1
        return true;
58
41
59
41
  for (const Stmt *Child : S->children())
60
31
    if (Child && containsStaticLocal(Child))
61
1
      return true;
62
41
63
41
  
return false40
;
64
41
}
65
66
// Recursively find any substatements containing __builtin_offsetof
67
40
bool containsBuiltinOffsetOf(const Stmt *S) {
68
40
  if (isa<OffsetOfExpr>(S))
69
0
    return true;
70
40
71
40
  for (const Stmt *Child : S->children())
72
30
    if (Child && containsBuiltinOffsetOf(Child))
73
0
      return true;
74
40
75
40
  return false;
76
40
}
77
78
// Extract lhs and rhs from assignment statement
79
std::pair<const clang::VarDecl *, const clang::Expr *>
80
22
parseAssignment(const Stmt *S) {
81
22
  const VarDecl *VD = nullptr;
82
22
  const Expr *RHS = nullptr;
83
22
84
22
  if (auto Assign = dyn_cast_or_null<BinaryOperator>(S)) {
85
6
    if (Assign->isAssignmentOp()) {
86
2
      // Ordinary assignment
87
2
      RHS = Assign->getRHS();
88
2
      if (auto DE = dyn_cast_or_null<DeclRefExpr>(Assign->getLHS()))
89
2
        VD = dyn_cast_or_null<VarDecl>(DE->getDecl());
90
2
    }
91
16
  } else if (auto PD = dyn_cast_or_null<DeclStmt>(S)) {
92
8
    // Initialization
93
8
    assert(PD->isSingleDecl() && "We process decls one by one");
94
8
    VD = dyn_cast_or_null<VarDecl>(PD->getSingleDecl());
95
8
    RHS = VD->getAnyInitializer();
96
8
  }
97
22
98
22
  return std::make_pair(VD, RHS);
99
22
}
100
101
3.96k
Nullability getNullabilityAnnotation(QualType Type) {
102
3.96k
  const auto *AttrType = Type->getAs<AttributedType>();
103
3.96k
  if (!AttrType)
104
2.09k
    return Nullability::Unspecified;
105
1.87k
  if (AttrType->getAttrKind() == attr::TypeNullable)
106
548
    return Nullability::Nullable;
107
1.32k
  else if (AttrType->getAttrKind() == attr::TypeNonNull)
108
1.32k
    return Nullability::Nonnull;
109
0
  return Nullability::Unspecified;
110
0
}
111
112
113
} // end namespace ento
114
} // end namespace clang