Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/CheckedArithmetic.h
Line
Count
Source (jump to first uncovered line)
1
//==-- llvm/Support/CheckedArithmetic.h - Safe arithmetical operations *- 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 contains generic functions for operating on integers which
10
// give the indication on whether the operation has overflown.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_SUPPORT_CHECKEDARITHMETIC_H
15
#define LLVM_SUPPORT_CHECKEDARITHMETIC_H
16
17
#include "llvm/ADT/APInt.h"
18
#include "llvm/ADT/Optional.h"
19
20
#include <type_traits>
21
22
namespace {
23
24
/// Utility function to apply a given method of \c APInt \p F to \p LHS and
25
/// \p RHS.
26
/// \return Empty optional if the operation overflows, or result otherwise.
27
template <typename T, typename F>
28
typename std::enable_if<std::is_integral<T>::value && sizeof(T) * 8 <= 64,
29
                        llvm::Optional<T>>::type
30
11.5k
checkedOp(T LHS, T RHS, F Op, bool Signed = true) {
31
11.5k
  llvm::APInt ALHS(/*BitSize=*/sizeof(T) * 8, LHS, Signed);
32
11.5k
  llvm::APInt ARHS(/*BitSize=*/sizeof(T) * 8, RHS, Signed);
33
11.5k
  bool Overflow;
34
11.5k
  llvm::APInt Out = (ALHS.*Op)(ARHS, Overflow);
35
11.5k
  if (Overflow)
36
7
    return llvm::None;
37
11.5k
  return Signed ? Out.getSExtValue() : 
Out.getZExtValue()0
;
38
11.5k
}
VectorUtils.cpp:std::__1::enable_if<(std::is_integral<int>::value) && (((sizeof (int)) * (8)) <= (64)), llvm::Optional<int> >::type (anonymous namespace)::checkedOp<int, llvm::APInt (llvm::APInt::*)(llvm::APInt const&, bool&) const>(int, int, llvm::APInt (llvm::APInt::*)(llvm::APInt const&, bool&) const, bool)
Line
Count
Source
30
5.29k
checkedOp(T LHS, T RHS, F Op, bool Signed = true) {
31
5.29k
  llvm::APInt ALHS(/*BitSize=*/sizeof(T) * 8, LHS, Signed);
32
5.29k
  llvm::APInt ARHS(/*BitSize=*/sizeof(T) * 8, RHS, Signed);
33
5.29k
  bool Overflow;
34
5.29k
  llvm::APInt Out = (ALHS.*Op)(ARHS, Overflow);
35
5.29k
  if (Overflow)
36
1
    return llvm::None;
37
5.29k
  return Signed ? Out.getSExtValue() : 
Out.getZExtValue()0
;
38
5.29k
}
VPlan.cpp:std::__1::enable_if<(std::is_integral<int>::value) && (((sizeof (int)) * (8)) <= (64)), llvm::Optional<int> >::type (anonymous namespace)::checkedOp<int, llvm::APInt (llvm::APInt::*)(llvm::APInt const&, bool&) const>(int, int, llvm::APInt (llvm::APInt::*)(llvm::APInt const&, bool&) const, bool)
Line
Count
Source
30
81
checkedOp(T LHS, T RHS, F Op, bool Signed = true) {
31
81
  llvm::APInt ALHS(/*BitSize=*/sizeof(T) * 8, LHS, Signed);
32
81
  llvm::APInt ARHS(/*BitSize=*/sizeof(T) * 8, RHS, Signed);
33
81
  bool Overflow;
34
81
  llvm::APInt Out = (ALHS.*Op)(ARHS, Overflow);
35
81
  if (Overflow)
36
0
    return llvm::None;
37
81
  return Signed ? Out.getSExtValue() : 
Out.getZExtValue()0
;
38
81
}
MemRegion.cpp:std::__1::enable_if<(std::is_integral<long long>::value) && (((sizeof (long long)) * (8)) <= (64)), llvm::Optional<long long> >::type (anonymous namespace)::checkedOp<long long, llvm::APInt (llvm::APInt::*)(llvm::APInt const&, bool&) const>(long long, long long, llvm::APInt (llvm::APInt::*)(llvm::APInt const&, bool&) const, bool)
Line
Count
Source
30
6.20k
checkedOp(T LHS, T RHS, F Op, bool Signed = true) {
31
6.20k
  llvm::APInt ALHS(/*BitSize=*/sizeof(T) * 8, LHS, Signed);
32
6.20k
  llvm::APInt ARHS(/*BitSize=*/sizeof(T) * 8, RHS, Signed);
33
6.20k
  bool Overflow;
34
6.20k
  llvm::APInt Out = (ALHS.*Op)(ARHS, Overflow);
35
6.20k
  if (Overflow)
36
6
    return llvm::None;
37
6.20k
  return Signed ? Out.getSExtValue() : 
Out.getZExtValue()0
;
38
6.20k
}
39
}
40
41
namespace llvm {
42
43
/// Add two signed integers \p LHS and \p RHS.
44
/// \return Optional of sum if no signed overflow occurred,
45
/// \c None otherwise.
46
template <typename T>
47
typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
48
6.13k
checkedAdd(T LHS, T RHS) {
49
6.13k
  return checkedOp(LHS, RHS, &llvm::APInt::sadd_ov);
50
6.13k
}
std::__1::enable_if<std::is_signed<int>::value, llvm::Optional<int> >::type llvm::checkedAdd<int>(int, int)
Line
Count
Source
48
3.02k
checkedAdd(T LHS, T RHS) {
49
3.02k
  return checkedOp(LHS, RHS, &llvm::APInt::sadd_ov);
50
3.02k
}
std::__1::enable_if<std::is_signed<long long>::value, llvm::Optional<long long> >::type llvm::checkedAdd<long long>(long long, long long)
Line
Count
Source
48
3.10k
checkedAdd(T LHS, T RHS) {
49
3.10k
  return checkedOp(LHS, RHS, &llvm::APInt::sadd_ov);
50
3.10k
}
51
52
/// Subtract two signed integers \p LHS and \p RHS.
53
/// \return Optional of sum if no signed overflow occurred,
54
/// \c None otherwise.
55
template <typename T>
56
typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
57
2.35k
checkedSub(T LHS, T RHS) {
58
2.35k
  return checkedOp(LHS, RHS, &llvm::APInt::ssub_ov);
59
2.35k
}
60
61
/// Multiply two signed integers \p LHS and \p RHS.
62
/// \return Optional of product if no signed overflow occurred,
63
/// \c None otherwise.
64
template <typename T>
65
typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
66
3.11k
checkedMul(T LHS, T RHS) {
67
3.11k
  return checkedOp(LHS, RHS, &llvm::APInt::smul_ov);
68
3.11k
}
69
70
/// Multiply A and B, and add C to the resulting product.
71
/// \return Optional of result if no signed overflow occurred,
72
/// \c None otherwise.
73
template <typename T>
74
typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
75
3.11k
checkedMulAdd(T A, T B, T C) {
76
3.11k
  if (auto Product = checkedMul(A, B))
77
3.10k
    return checkedAdd(*Product, C);
78
6
  return llvm::None;
79
6
}
80
81
/// Add two unsigned integers \p LHS and \p RHS.
82
/// \return Optional of sum if no unsigned overflow occurred,
83
/// \c None otherwise.
84
template <typename T>
85
typename std::enable_if<std::is_unsigned<T>::value, llvm::Optional<T>>::type
86
checkedAddUnsigned(T LHS, T RHS) {
87
  return checkedOp(LHS, RHS, &llvm::APInt::uadd_ov, /*Signed=*/false);
88
}
89
90
/// Multiply two unsigned integers \p LHS and \p RHS.
91
/// \return Optional of product if no unsigned overflow occurred,
92
/// \c None otherwise.
93
template <typename T>
94
typename std::enable_if<std::is_unsigned<T>::value, llvm::Optional<T>>::type
95
checkedMulUnsigned(T LHS, T RHS) {
96
  return checkedOp(LHS, RHS, &llvm::APInt::umul_ov, /*Signed=*/false);
97
}
98
99
/// Multiply unsigned integers A and B, and add C to the resulting product.
100
/// \return Optional of result if no unsigned overflow occurred,
101
/// \c None otherwise.
102
template <typename T>
103
typename std::enable_if<std::is_unsigned<T>::value, llvm::Optional<T>>::type
104
checkedMulAddUnsigned(T A, T B, T C) {
105
  if (auto Product = checkedMulUnsigned(A, B))
106
    return checkedAddUnsigned(*Product, C);
107
  return llvm::None;
108
}
109
110
} // End llvm namespace
111
112
#endif