• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CONSCRYPT_MACROS_H_
18 #define CONSCRYPT_MACROS_H_
19 
20 #define TO_STRING1(x) #x
21 #define TO_STRING(x) TO_STRING1(x)
22 #ifndef JNI_JARJAR_PREFIX
23 #ifndef CONSCRYPT_NOT_UNBUNDLED
24 #define CONSCRYPT_UNBUNDLED
25 #endif
26 #define JNI_JARJAR_PREFIX
27 #endif
28 
29 // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
30 // between switch labels:
31 //  switch (x) {
32 //    case 40:
33 //    case 41:
34 //      if (truth_is_out_there) {
35 //        ++x;
36 //        FALLTHROUGH_INTENDED;  // Use instead of/along with annotations in
37 //                               // comments.
38 //      } else {
39 //        return x;
40 //      }
41 //    case 42:
42 //      ...
43 //
44 //  As shown in the example above, the FALLTHROUGH_INTENDED macro should be
45 //  followed by a semicolon. It is designed to mimic control-flow statements
46 //  like 'break;', so it can be placed in most places where 'break;' can, but
47 //  only if there are no statements on the execution path between it and the
48 //  next switch label.
49 //
50 //  When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is
51 //  expanded to [[clang::fallthrough]] attribute, which is analysed when
52 //  performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').
53 //  See clang documentation on language extensions for details:
54 //  http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough
55 //
56 //  When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
57 //  effect on diagnostics.
58 //
59 //  In either case this macro has no effect on runtime behavior and performance
60 //  of code.
61 #if defined(__clang__) && __cplusplus >= 201103L && defined(__has_warning)
62 #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
63 #define FALLTHROUGH_INTENDED [[clang::fallthrough]]  // NOLINT
64 #endif
65 #endif
66 
67 #ifndef FALLTHROUGH_INTENDED
68 #define FALLTHROUGH_INTENDED \
69     do {                     \
70     } while (0)
71 #endif
72 
73 #if defined _WIN32 || defined __CYGWIN__
74 #ifdef __GNUC__
75 #define CONSCRYPT_PUBLIC __attribute__((dllexport))
76 #else
77 #define CONSCRYPT_PUBLIC __declspec(dllexport)
78 #endif
79 #define CONSCRYPT_LOCAL
80 #else
81 #if __GNUC__ >= 4
82 #define CONSCRYPT_PUBLIC __attribute__((visibility("default")))
83 #define CONSCRYPT_LOCAL __attribute__((visibility("hidden")))
84 #else
85 #define CONSCRYPT_PUBLIC
86 #define CONSCRYPT_LOCAL
87 #endif
88 #endif
89 
90 #ifdef __GNUC__
91 #define CONSCRYPT_UNUSED __attribute__((unused))
92 #define CONSCRYPT_WARN_UNUSED __attribute__((warn_unused_result))
93 #elif defined(_WIN32)
94 #define CONSCRYPT_UNUSED __pragma(warning(suppress : 4100))
95 #define CONSCRYPT_WARN_UNUSED _Check_return_
96 #else
97 #define CONSCRYPT_UNUSED
98 #define CONSCRYPT_WARN_UNUSED
99 #endif
100 
101 #ifndef NELEM
102 #define NELEM(x) (static_cast<int>(sizeof(x) / sizeof((x)[0])))
103 #endif
104 
105 /**
106  * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
107  * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
108  * without triggering a warning by not using the result of release().
109  */
110 #define OWNERSHIP_TRANSFERRED(obj)                                           \
111     do {                                                                     \
112         decltype((obj).release()) CONSCRYPT_UNUSED _dummy = (obj).release(); \
113     } while (0)
114 
115 /**
116  * UNUSED_ARGUMENT can be used to mark an, otherwise unused, argument as "used"
117  * for the purposes of -Werror=unused-parameter. This can be needed when an
118  * argument's use is based on an #ifdef.
119  */
120 #define UNUSED_ARGUMENT(x) ((void)(x));
121 
122 /**
123  * Check array bounds for arguments when an array and offset are given.
124  */
125 #define ARRAY_OFFSET_INVALID(array, offset) \
126     ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size()))
127 
128 /**
129  * Check array bounds for arguments when an array, offset, and length are given.
130  */
131 #define ARRAY_OFFSET_LENGTH_INVALID(array, offset, len)                              \
132     ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size()) || (len) < 0 || \
133      (len) > static_cast<ssize_t>((array).size()) - (offset))
134 
135 /**
136  * Check array bounds for arguments when an array length, chunk offset, and chunk length are given.
137  */
138 #define ARRAY_CHUNK_INVALID(array_len, chunk_offset, chunk_len)                                   \
139     ((chunk_offset) < 0 || (chunk_offset) > static_cast<ssize_t>(array_len) || (chunk_len) < 0 || \
140      (chunk_len) > static_cast<ssize_t>(array_len) - (chunk_offset))
141 
142 #endif  // CONSCRYPT_MACROS_H_
143