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