Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef MATH_UTILS_H
12 : #define MATH_UTILS_H
13 :
14 : #include <climits>
15 : #include "acl/acl_base.h"
16 : #include "common/log_inner.h"
17 :
18 : namespace acl {
19 :
20 14 : inline aclError CheckSizeTMultiOverflow(const size_t a, const size_t b, size_t& res)
21 : {
22 14 : if ((a != 0U) && (b != 0U) && ((SIZE_MAX / a) < b)) {
23 0 : ACL_LOG_ERROR("[Check][Overflow]%zu multiplies %zu overflow", a, b);
24 0 : return ACL_ERROR_FAILURE;
25 : }
26 14 : res = a * b;
27 14 : return ACL_SUCCESS;
28 : }
29 :
30 : inline aclError CheckUint32MultiOverflow(const uint32_t a, const uint32_t b, uint32_t& res)
31 : {
32 : if ((a != 0U) && (b != 0U) && ((UINT32_MAX / a) < b)) {
33 : ACL_LOG_ERROR("[Check][Overflow]%u multiplies %u overflow", a, b);
34 : return ACL_ERROR_FAILURE;
35 : }
36 : res = a * b;
37 : return ACL_SUCCESS;
38 : }
39 :
40 : inline aclError CheckIntAddOverflow(const int32_t a, const int32_t b, int32_t& res)
41 : {
42 : if (((b > 0) && (a > (INT_MAX - b))) || ((b < 0) && (a < (INT_MIN - b)))) {
43 : ACL_LOG_ERROR("[Check][Overflow]%d adds %d overflow", a, b);
44 : return ACL_ERROR_FAILURE;
45 : }
46 : res = a + b;
47 : return ACL_SUCCESS;
48 : }
49 :
50 32 : inline aclError CheckSizeTAddOverflow(const size_t a, const size_t b, size_t& res)
51 : {
52 32 : if (a > (SIZE_MAX - b)) {
53 4 : ACL_LOG_ERROR("[Check][Overflow]%zu adds %zu overflow", a, b);
54 4 : return ACL_ERROR_FAILURE;
55 : }
56 28 : res = a + b;
57 28 : return ACL_SUCCESS;
58 : }
59 :
60 : inline aclError CheckUint32AddOverflow(const uint32_t a, const uint32_t b, uint32_t& res)
61 : {
62 : if (a > (UINT32_MAX - b)) {
63 : ACL_LOG_ERROR("[Check][Overflow]%u adds %u overflow", a, b);
64 : return ACL_ERROR_FAILURE;
65 : }
66 : res = a + b;
67 : return ACL_SUCCESS;
68 : }
69 : } // namespace acl
70 :
71 : #define ACL_CHECK_ASSIGN_SIZET_MULTI(a, b, res) \
72 : do { \
73 : const aclError ret = acl::CheckSizeTMultiOverflow((a), (b), (res)); \
74 : if (ret != ACL_SUCCESS) { \
75 : return ret; \
76 : } \
77 : } while (false)
78 :
79 : #define ACL_CHECK_ASSIGN_SIZET_MULTI_RET_NUM(a, b, res) \
80 : do { \
81 : const aclError ret = acl::CheckSizeTMultiOverflow((a), (b), (res)); \
82 : if (ret != ACL_SUCCESS) { \
83 : return 0U; \
84 : } \
85 : } while (false)
86 :
87 : #define ACL_CHECK_ASSIGN_UINT32_MULTI(a, b, res) \
88 : do { \
89 : const aclError ret = acl::CheckUint32MultiOverflow((a), (b), (res)); \
90 : if (ret != ACL_SUCCESS) { \
91 : return ret; \
92 : } \
93 : } while (false)
94 :
95 : #define ACL_CHECK_ASSIGN_INT32_ADD(a, b, res) \
96 : do { \
97 : const aclError ret = acl::CheckIntAddOverflow((a), (b), (res)); \
98 : if (ret != ACL_SUCCESS) { \
99 : return ret; \
100 : } \
101 : } while (false)
102 :
103 : #define ACL_CHECK_ASSIGN_SIZET_ADD(a, b, res) \
104 : do { \
105 : const aclError ret = acl::CheckSizeTAddOverflow((a), (b), (res)); \
106 : if (ret != ACL_SUCCESS) { \
107 : return ret; \
108 : } \
109 : } while (false)
110 :
111 : #define ACL_CHECK_ASSIGN_UINT32T_ADD(a, b, res) \
112 : do { \
113 : const aclError ret = acl::CheckUint32AddOverflow((a), (b), (res)); \
114 : if (ret != ACL_SUCCESS) { \
115 : return ret; \
116 : } \
117 : } while (false)
118 :
119 : #endif // MATH_UTILS_H
|