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_SRC_MAIN_NATIVE_MACROS_H_ 18 #define CONSCRYPT_SRC_MAIN_NATIVE_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) ((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 // Define logging macros... 143 144 #define LOG_TAG "NativeCrypto" 145 146 #ifndef CONSCRYPT_UNBUNDLED 147 148 #include <log/log.h> 149 150 #elif defined(ANDROID) && !defined(CONSCRYPT_OPENJDK) 151 152 #include <android/log.h> 153 #ifndef ALOG 154 #define ALOG(priority, tag, ...) __android_log_print(ANDROID_##priority, tag, __VA_ARGS__) 155 #endif 156 #ifndef ALOGD 157 #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 158 #endif 159 #ifndef ALOGE 160 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 161 #endif 162 163 #ifndef __ALOGV 164 #define __ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) 165 #endif 166 #ifndef ALOGV 167 #if LOG_NDEBUG 168 #define ALOGV(...) \ 169 do { \ 170 if (0) { \ 171 __ALOGV(__VA_ARGS__); \ 172 } \ 173 } while (0) 174 #else 175 #define ALOGV(...) __ALOGV(__VA_ARGS__) 176 #endif 177 #endif 178 179 #else // !ANDROID 180 181 #define LOG_INFO ((void)0) 182 183 #define ALOG(...) VA_ARGS_UNUSED(__VA_ARGS__) 184 #define ALOGD(...) VA_ARGS_UNUSED(__VA_ARGS__) 185 #define ALOGE(...) VA_ARGS_UNUSED(__VA_ARGS__) 186 #define ALOGV(...) VA_ARGS_UNUSED(__VA_ARGS__) 187 188 #define UNUSED_1(a) ((void)(a)) 189 #define UNUSED_2(a, b) ((void)(a)), UNUSED_1(b) 190 #define UNUSED_3(a, b, c) ((void)(a)), UNUSED_2(b, c) 191 #define UNUSED_4(a, b, c, d) ((void)(a)), UNUSED_3(b, c, d) 192 #define UNUSED_5(a, b, c, d, e) ((void)(a)), UNUSED_4(b, c, d, e) 193 #define UNUSED_6(a, b, c, d, e, f) ((void)(a)), UNUSED_5(b, c, d, e, f) 194 #define UNUSED_7(a, b, c, d, e, f, g) ((void)(a)), UNUSED_6(b, c, d, e, f, g) 195 #define UNUSED_8(a, b, c, d, e, f, g, h) ((void)(a)), UNUSED_7(b, c, d, e, f, g, h) 196 #define UNUSED_9(a, b, c, d, e, f, g, h, i) ((void)(a)), UNUSED_8(b, c, d, e, f, g, h, i) 197 #define UNUSED_10(a, b, c, d, e, f, g, h, i, j) ((void)(a)), UNUSED_9(b, c, d, e, f, g, h, i, j) 198 #define UNUSED_11(a, b, c, d, e, f, g, h, i, j, k) \ 199 ((void)(a)), UNUSED_10(b, c, d, e, f, g, h, i, j, k) 200 #define UNUSED_12(a, b, c, d, e, f, g, h, i, j, k, l) \ 201 ((void)(a)), UNUSED_11(b, c, d, e, f, g, h, i, j, k, l) 202 #define UNUSED_13(a, b, c, d, e, f, g, h, i, j, k, l, m) \ 203 ((void)(a)), UNUSED_12(b, c, d, e, f, g, h, i, j, k, l, m) 204 #define UNUSED_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \ 205 ((void)(a)), UNUSED_13(b, c, d, e, f, g, h, i, j, k, l, m, n) 206 207 #define VA_ARGS_UNUSED_IMPL_(num) UNUSED_##num 208 #define VA_ARGS_UNUSED_IMPL(num) VA_ARGS_UNUSED_IMPL_(num) 209 210 #define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, N, ...) N 211 #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 212 213 #define VA_ARGS_UNUSED(...) VA_ARGS_UNUSED_IMPL(VA_NARGS(__VA_ARGS__))(__VA_ARGS__) 214 215 #endif // !ANDROID 216 217 #endif // CONSCRYPT_SRC_MAIN_NATIVE_MACROS_H_ 218