1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #ifndef INCLUDED_O3TL_SAFEINT_HXX
11 #define INCLUDED_O3TL_SAFEINT_HXX
18 # define __has_builtin(x) 0
27 template<typename T
> inline bool checked_multiply(T a
, T b
, T
& result
)
29 return !msl::utilities::SafeMultiply(a
, b
, result
);
32 template<typename T
> inline bool checked_add(T a
, T b
, T
& result
)
34 return !msl::utilities::SafeAdd(a
, b
, result
);
37 #elif (defined __GNUC__ && __GNUC__ >= 5) || (__has_builtin(__builtin_mul_overflow) && !(defined ANDROID && defined __clang__))
39 template<typename T
> inline bool checked_multiply(T a
, T b
, T
& result
)
41 return __builtin_mul_overflow(a
, b
, &result
);
44 template<typename T
> inline bool checked_add(T a
, T b
, T
& result
)
46 return __builtin_add_overflow(a
, b
, &result
);
51 //https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
52 template<typename T
> inline typename
std::enable_if
<std::is_signed
<T
>::value
, bool>::type
checked_multiply(T a
, T b
, T
& result
)
54 if (a
> 0) { /* a is positive */
55 if (b
> 0) { /* a and b are positive */
56 if (a
> (std::numeric_limits
<T
>::max() / b
)) {
57 return true; /* Handle error */
59 } else { /* a positive, b nonpositive */
60 if (b
< (std::numeric_limits
<T
>::min() / a
)) {
61 return true; /* Handle error */
63 } /* a positive, b nonpositive */
64 } else { /* a is nonpositive */
65 if (b
> 0) { /* a is nonpositive, b is positive */
66 if (a
< (std::numeric_limits
<T
>::min() / b
)) {
67 return true; /* Handle error */
69 } else { /* a and b are nonpositive */
70 if ( (a
!= 0) && (b
< (std::numeric_limits
<T
>::max() / a
))) {
71 return true; /* Handle error */
73 } /* End if a and b are nonpositive */
74 } /* End if a is nonpositive */
81 //https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
82 template<typename T
> inline typename
std::enable_if
<std::is_unsigned
<T
>::value
, bool>::type
checked_multiply(T a
, T b
, T
& result
)
84 if (b
&& a
> std::numeric_limits
<T
>::max() / b
) {
85 return true;/* Handle error */
93 //https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
94 template<typename T
> inline typename
std::enable_if
<std::is_signed
<T
>::value
, bool>::type
checked_add(T a
, T b
, T
& result
)
96 if (((b
> 0) && (a
> (std::numeric_limits
<T
>::max() - b
))) ||
97 ((b
< 0) && (a
< (std::numeric_limits
<T
>::min() - b
)))) {
106 //https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
107 template<typename T
> inline typename
std::enable_if
<std::is_unsigned
<T
>::value
, bool>::type
checked_add(T a
, T b
, T
& result
)
109 if (std::numeric_limits
<T
>::max() - a
< b
) {
110 return true;/* Handle error */
124 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */