macros.h revision 5fdfec1dbfefa9ac64e464fcd43038bceed6544b
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_ATTRIBUTE_1(value) __attribute__(value) 92#else 93#define CONSCRYPT_ATTRIBUTE_1(value) 94#endif 95 96#define CONSCRYPT_NATIVE_METHOD(className, functionName, signature) \ 97 { \ 98 (char*)#functionName, (char*)(signature), \ 99 reinterpret_cast<void*>(className##_##functionName) \ 100 } 101 102#ifndef NELEM 103#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0]))) 104#endif 105 106/** 107 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument 108 * on failure. This means we need to tell our scoped pointers when we've transferred ownership, 109 * without triggering a warning by not using the result of release(). 110 */ 111#define OWNERSHIP_TRANSFERRED(obj) \ 112 do { \ 113 decltype((obj).release()) _dummy CONSCRYPT_ATTRIBUTE_1((unused)) = (obj).release(); \ 114 } while (0) 115 116/** 117 * UNUSED_ARGUMENT can be used to mark an, otherwise unused, argument as "used" 118 * for the purposes of -Werror=unused-parameter. This can be needed when an 119 * argument's use is based on an #ifdef. 120 */ 121#define UNUSED_ARGUMENT(x) ((void)(x)); 122 123/** 124 * Check array bounds for arguments when an array and offset are given. 125 */ 126#define ARRAY_OFFSET_INVALID(array, offset) \ 127 ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size())) 128 129/** 130 * Check array bounds for arguments when an array, offset, and length are given. 131 */ 132#define ARRAY_OFFSET_LENGTH_INVALID(array, offset, len) \ 133 ((offset) < 0 || (offset) > static_cast<ssize_t>((array).size()) || (len) < 0 || \ 134 (len) > static_cast<ssize_t>((array).size()) - (offset)) 135 136/** 137 * Check array bounds for arguments when an array length, chunk offset, and chunk length are given. 138 */ 139#define ARRAY_CHUNK_INVALID(array_len, chunk_offset, chunk_len) \ 140 ((chunk_offset) < 0 || (chunk_offset) > static_cast<ssize_t>(array_len) || (chunk_len) < 0 || \ 141 (chunk_len) > static_cast<ssize_t>(array_len) - (chunk_offset)) 142 143// Define logging macros... 144 145#define LOG_TAG "NativeCrypto" 146 147#ifndef CONSCRYPT_UNBUNDLED 148 149#include <log/log.h> 150 151#elif defined(ANDROID) && !defined(CONSCRYPT_OPENJDK) 152 153#include <android/log.h> 154#ifndef ALOG 155#define ALOG(priority, tag, ...) __android_log_print(ANDROID_##priority, tag, __VA_ARGS__) 156#endif 157#ifndef ALOGD 158#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 159#endif 160#ifndef ALOGE 161#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 162#endif 163 164#ifndef __ALOGV 165#define __ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) 166#endif 167#ifndef ALOGV 168#if LOG_NDEBUG 169#define ALOGV(...) \ 170 do { \ 171 if (0) { \ 172 __ALOGV(__VA_ARGS__); \ 173 } \ 174 } while (0) 175#else 176#define ALOGV(...) __ALOGV(__VA_ARGS__) 177#endif 178#endif 179 180#else // !ANDROID 181 182#define LOG_INFO ((void)0) 183 184#define ALOG(...) VA_ARGS_UNUSED(__VA_ARGS__) 185#define ALOGD(...) VA_ARGS_UNUSED(__VA_ARGS__) 186#define ALOGE(...) VA_ARGS_UNUSED(__VA_ARGS__) 187#define ALOGV(...) VA_ARGS_UNUSED(__VA_ARGS__) 188 189#define UNUSED_1(a) ((void)(a)) 190#define UNUSED_2(a, b) ((void)(a)), UNUSED_1(b) 191#define UNUSED_3(a, b, c) ((void)(a)), UNUSED_2(b, c) 192#define UNUSED_4(a, b, c, d) ((void)(a)), UNUSED_3(b, c, d) 193#define UNUSED_5(a, b, c, d, e) ((void)(a)), UNUSED_4(b, c, d, e) 194#define UNUSED_6(a, b, c, d, e, f) ((void)(a)), UNUSED_5(b, c, d, e, f) 195#define UNUSED_7(a, b, c, d, e, f, g) ((void)(a)), UNUSED_6(b, c, d, e, f, g) 196#define UNUSED_8(a, b, c, d, e, f, g, h) ((void)(a)), UNUSED_7(b, c, d, e, f, g, h) 197#define UNUSED_9(a, b, c, d, e, f, g, h, i) ((void)(a)), UNUSED_8(b, c, d, e, f, g, h, i) 198#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) 199#define UNUSED_11(a, b, c, d, e, f, g, h, i, j, k) \ 200 ((void)(a)), UNUSED_10(b, c, d, e, f, g, h, i, j, k) 201#define UNUSED_12(a, b, c, d, e, f, g, h, i, j, k, l) \ 202 ((void)(a)), UNUSED_11(b, c, d, e, f, g, h, i, j, k, l) 203#define UNUSED_13(a, b, c, d, e, f, g, h, i, j, k, l, m) \ 204 ((void)(a)), UNUSED_12(b, c, d, e, f, g, h, i, j, k, l, m) 205#define UNUSED_14(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \ 206 ((void)(a)), UNUSED_13(b, c, d, e, f, g, h, i, j, k, l, m, n) 207 208#define VA_ARGS_UNUSED_IMPL_(num) UNUSED_##num 209#define VA_ARGS_UNUSED_IMPL(num) VA_ARGS_UNUSED_IMPL_(num) 210 211#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, N, ...) N 212#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 213 214#define VA_ARGS_UNUSED(...) VA_ARGS_UNUSED_IMPL(VA_NARGS(__VA_ARGS__))(__VA_ARGS__) 215 216#endif // !ANDROID 217 218#endif // CONSCRYPT_SRC_MAIN_NATIVE_MACROS_H_ 219