17c2aad20Sopenharmony_ci/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 27c2aad20Sopenharmony_ci 37c2aad20Sopenharmony_ci#ifndef __LINUX_OVERFLOW_H 47c2aad20Sopenharmony_ci#define __LINUX_OVERFLOW_H 57c2aad20Sopenharmony_ci 67c2aad20Sopenharmony_ci#define is_signed_type(type) (((type)(-1)) < (type)1) 77c2aad20Sopenharmony_ci#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) 87c2aad20Sopenharmony_ci#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) 97c2aad20Sopenharmony_ci#define type_min(T) ((T)((T)-type_max(T)-(T)1)) 107c2aad20Sopenharmony_ci 117c2aad20Sopenharmony_ci#ifndef unlikely 127c2aad20Sopenharmony_ci#define unlikely(x) __builtin_expect(!!(x), 0) 137c2aad20Sopenharmony_ci#endif 147c2aad20Sopenharmony_ci 157c2aad20Sopenharmony_ci#ifdef __GNUC__ 167c2aad20Sopenharmony_ci#define GCC_VERSION (__GNUC__ * 10000 \ 177c2aad20Sopenharmony_ci + __GNUC_MINOR__ * 100 \ 187c2aad20Sopenharmony_ci + __GNUC_PATCHLEVEL__) 197c2aad20Sopenharmony_ci#if GCC_VERSION >= 50100 207c2aad20Sopenharmony_ci#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 217c2aad20Sopenharmony_ci#endif 227c2aad20Sopenharmony_ci#endif 237c2aad20Sopenharmony_ci 247c2aad20Sopenharmony_ci#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 257c2aad20Sopenharmony_ci 267c2aad20Sopenharmony_ci#define check_mul_overflow(a, b, d) ({ \ 277c2aad20Sopenharmony_ci typeof(a) __a = (a); \ 287c2aad20Sopenharmony_ci typeof(b) __b = (b); \ 297c2aad20Sopenharmony_ci typeof(d) __d = (d); \ 307c2aad20Sopenharmony_ci (void) (&__a == &__b); \ 317c2aad20Sopenharmony_ci (void) (&__a == __d); \ 327c2aad20Sopenharmony_ci __builtin_mul_overflow(__a, __b, __d); \ 337c2aad20Sopenharmony_ci}) 347c2aad20Sopenharmony_ci 357c2aad20Sopenharmony_ci#else 367c2aad20Sopenharmony_ci 377c2aad20Sopenharmony_ci/* 387c2aad20Sopenharmony_ci * If one of a or b is a compile-time constant, this avoids a division. 397c2aad20Sopenharmony_ci */ 407c2aad20Sopenharmony_ci#define __unsigned_mul_overflow(a, b, d) ({ \ 417c2aad20Sopenharmony_ci typeof(a) __a = (a); \ 427c2aad20Sopenharmony_ci typeof(b) __b = (b); \ 437c2aad20Sopenharmony_ci typeof(d) __d = (d); \ 447c2aad20Sopenharmony_ci (void) (&__a == &__b); \ 457c2aad20Sopenharmony_ci (void) (&__a == __d); \ 467c2aad20Sopenharmony_ci *__d = __a * __b; \ 477c2aad20Sopenharmony_ci __builtin_constant_p(__b) ? \ 487c2aad20Sopenharmony_ci __b > 0 && __a > type_max(typeof(__a)) / __b : \ 497c2aad20Sopenharmony_ci __a > 0 && __b > type_max(typeof(__b)) / __a; \ 507c2aad20Sopenharmony_ci}) 517c2aad20Sopenharmony_ci 527c2aad20Sopenharmony_ci/* 537c2aad20Sopenharmony_ci * Signed multiplication is rather hard. gcc always follows C99, so 547c2aad20Sopenharmony_ci * division is truncated towards 0. This means that we can write the 557c2aad20Sopenharmony_ci * overflow check like this: 567c2aad20Sopenharmony_ci * 577c2aad20Sopenharmony_ci * (a > 0 && (b > MAX/a || b < MIN/a)) || 587c2aad20Sopenharmony_ci * (a < -1 && (b > MIN/a || b < MAX/a) || 597c2aad20Sopenharmony_ci * (a == -1 && b == MIN) 607c2aad20Sopenharmony_ci * 617c2aad20Sopenharmony_ci * The redundant casts of -1 are to silence an annoying -Wtype-limits 627c2aad20Sopenharmony_ci * (included in -Wextra) warning: When the type is u8 or u16, the 637c2aad20Sopenharmony_ci * __b_c_e in check_mul_overflow obviously selects 647c2aad20Sopenharmony_ci * __unsigned_mul_overflow, but unfortunately gcc still parses this 657c2aad20Sopenharmony_ci * code and warns about the limited range of __b. 667c2aad20Sopenharmony_ci */ 677c2aad20Sopenharmony_ci 687c2aad20Sopenharmony_ci#define __signed_mul_overflow(a, b, d) ({ \ 697c2aad20Sopenharmony_ci typeof(a) __a = (a); \ 707c2aad20Sopenharmony_ci typeof(b) __b = (b); \ 717c2aad20Sopenharmony_ci typeof(d) __d = (d); \ 727c2aad20Sopenharmony_ci typeof(a) __tmax = type_max(typeof(a)); \ 737c2aad20Sopenharmony_ci typeof(a) __tmin = type_min(typeof(a)); \ 747c2aad20Sopenharmony_ci (void) (&__a == &__b); \ 757c2aad20Sopenharmony_ci (void) (&__a == __d); \ 767c2aad20Sopenharmony_ci *__d = (__u64)__a * (__u64)__b; \ 777c2aad20Sopenharmony_ci (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \ 787c2aad20Sopenharmony_ci (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \ 797c2aad20Sopenharmony_ci (__b == (typeof(__b))-1 && __a == __tmin); \ 807c2aad20Sopenharmony_ci}) 817c2aad20Sopenharmony_ci 827c2aad20Sopenharmony_ci#define check_mul_overflow(a, b, d) \ 837c2aad20Sopenharmony_ci __builtin_choose_expr(is_signed_type(typeof(a)), \ 847c2aad20Sopenharmony_ci __signed_mul_overflow(a, b, d), \ 857c2aad20Sopenharmony_ci __unsigned_mul_overflow(a, b, d)) 867c2aad20Sopenharmony_ci 877c2aad20Sopenharmony_ci 887c2aad20Sopenharmony_ci#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ 897c2aad20Sopenharmony_ci 907c2aad20Sopenharmony_ci#endif 91