builtins-overflow.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
  2. // expected-no-diagnostics
  3. #include <limits.h>
  4. #include <stdint.h>
  5. int a() {
  6. const int x = 3;
  7. static int z;
  8. constexpr int *y = &z;
  9. return []() { return __builtin_sub_overflow((int)x, (int)x, (int *)y); }();
  10. }
  11. int a2() {
  12. const int x = 3;
  13. static int z;
  14. constexpr int *y = &z;
  15. return []() { return __builtin_sub_overflow(x, x, y); }();
  16. }
  17. template<typename T>
  18. struct Result {
  19. bool B;
  20. T Value;
  21. constexpr bool operator==(const Result<T> &Other) {
  22. return B == Other.B && Value == Other.Value;
  23. }
  24. };
  25. template <typename RET, typename LHS, typename RHS>
  26. constexpr Result<RET> add(LHS &&lhs, RHS &&rhs) {
  27. RET sum{};
  28. return {__builtin_add_overflow(lhs, rhs, &sum), sum};
  29. }
  30. static_assert(add<short>(static_cast<char>(120), static_cast<char>(10)) == Result<short>{false, 130});
  31. static_assert(add<char>(static_cast<short>(120), static_cast<short>(10)) == Result<char>{true, -126});
  32. static_assert(add<unsigned int>(INT_MAX, INT_MAX) == Result<unsigned int>{false, static_cast<unsigned int>(INT_MAX) * 2u});
  33. static_assert(add<int>(static_cast<unsigned int>(INT_MAX), 1u) == Result<int>{true, INT_MIN});
  34. static_assert(add<int>(17, 22) == Result<int>{false, 39});
  35. static_assert(add<int>(INT_MAX - 22, 24) == Result<int>{true, INT_MIN + 1});
  36. static_assert(add<int>(INT_MIN + 22, -23) == Result<int>{true, INT_MAX});
  37. template <typename RET, typename LHS, typename RHS>
  38. constexpr Result<RET> sub(LHS &&lhs, RHS &&rhs) {
  39. RET sum{};
  40. return {__builtin_sub_overflow(lhs, rhs, &sum), sum};
  41. }
  42. static_assert(sub<unsigned char>(static_cast<char>(0),static_cast<char>(1)) == Result<unsigned char>{true, UCHAR_MAX});
  43. static_assert(sub<char>(static_cast<unsigned char>(0),static_cast<unsigned char>(1)) == Result<char>{false, -1});
  44. static_assert(sub<unsigned short>(static_cast<short>(0),static_cast<short>(1)) == Result<unsigned short>{true, USHRT_MAX});
  45. static_assert(sub<uint8_t>(static_cast<uint8_t>(255),static_cast<int>(100)) == Result<uint8_t>{false, 155});
  46. static_assert(sub<int>(17,22) == Result<int>{false, -5});
  47. static_assert(sub<int>(INT_MAX - 22, -23) == Result<int>{true, INT_MIN});
  48. static_assert(sub<int>(INT_MIN + 22, 23) == Result<int>{true, INT_MAX});
  49. template <typename RET, typename LHS, typename RHS>
  50. constexpr Result<RET> mul(LHS &&lhs, RHS &&rhs) {
  51. RET sum{};
  52. return {__builtin_mul_overflow(lhs, rhs, &sum), sum};
  53. }
  54. static_assert(mul<int>(17,22) == Result<int>{false, 374});
  55. static_assert(mul<int>(INT_MAX / 22, 23) == Result<int>{true, -2049870757});
  56. static_assert(mul<int>(INT_MIN / 22, -23) == Result<int>{true, -2049870757});
  57. constexpr Result<int> sadd(int lhs, int rhs) {
  58. int sum{};
  59. return {__builtin_sadd_overflow(lhs, rhs, &sum), sum};
  60. }
  61. static_assert(sadd(17,22) == Result<int>{false, 39});
  62. static_assert(sadd(INT_MAX - 22, 23) == Result<int>{true, INT_MIN});
  63. static_assert(sadd(INT_MIN + 22, -23) == Result<int>{true, INT_MAX});
  64. constexpr Result<int> ssub(int lhs, int rhs) {
  65. int sum{};
  66. return {__builtin_ssub_overflow(lhs, rhs, &sum), sum};
  67. }
  68. static_assert(ssub(17,22) == Result<int>{false, -5});
  69. static_assert(ssub(INT_MAX - 22, -23) == Result<int>{true, INT_MIN});
  70. static_assert(ssub(INT_MIN + 22, 23) == Result<int>{true, INT_MAX});
  71. constexpr Result<int> smul(int lhs, int rhs) {
  72. int sum{};
  73. return {__builtin_smul_overflow(lhs, rhs, &sum), sum};
  74. }
  75. static_assert(smul(17,22) == Result<int>{false, 374});
  76. static_assert(smul(INT_MAX / 22, 23) == Result<int>{true, -2049870757});
  77. static_assert(smul(INT_MIN / 22, -23) == Result<int>{true, -2049870757});