unsigned-overflow.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s
  2. // Verify checked operations are emitted for integers and longs.
  3. // unsigned short/char's tested in unsigned-promotion.c
  4. unsigned long li, lj, lk;
  5. unsigned int ii, ij, ik;
  6. extern void opaquelong(unsigned long);
  7. extern void opaqueint(unsigned int);
  8. // CHECK-LABEL: define void @testlongadd()
  9. void testlongadd() {
  10. // CHECK: [[T1:%.*]] = load i64* @lj
  11. // CHECK-NEXT: [[T2:%.*]] = load i64* @lk
  12. // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]])
  13. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
  14. // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
  15. // CHECK: call void @__ubsan_handle_add_overflow
  16. li = lj + lk;
  17. }
  18. // CHECK-LABEL: define void @testlongsub()
  19. void testlongsub() {
  20. // CHECK: [[T1:%.*]] = load i64* @lj
  21. // CHECK-NEXT: [[T2:%.*]] = load i64* @lk
  22. // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]])
  23. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
  24. // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
  25. // CHECK: call void @__ubsan_handle_sub_overflow
  26. li = lj - lk;
  27. }
  28. // CHECK-LABEL: define void @testlongmul()
  29. void testlongmul() {
  30. // CHECK: [[T1:%.*]] = load i64* @lj
  31. // CHECK-NEXT: [[T2:%.*]] = load i64* @lk
  32. // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]])
  33. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0
  34. // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1
  35. // CHECK: call void @__ubsan_handle_mul_overflow
  36. li = lj * lk;
  37. }
  38. // CHECK-LABEL: define void @testlongpostinc()
  39. void testlongpostinc() {
  40. opaquelong(li++);
  41. // CHECK: [[T1:%.*]] = load i64* @li
  42. // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
  43. // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
  44. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
  45. // CHECK: call void @__ubsan_handle_add_overflow
  46. }
  47. // CHECK-LABEL: define void @testlongpreinc()
  48. void testlongpreinc() {
  49. opaquelong(++li);
  50. // CHECK: [[T1:%.*]] = load i64* @li
  51. // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1)
  52. // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0
  53. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1
  54. // CHECK: call void @__ubsan_handle_add_overflow
  55. }
  56. // CHECK-LABEL: define void @testintadd()
  57. void testintadd() {
  58. // CHECK: [[T1:%.*]] = load i32* @ij
  59. // CHECK-NEXT: [[T2:%.*]] = load i32* @ik
  60. // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]])
  61. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
  62. // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
  63. // CHECK: call void @__ubsan_handle_add_overflow
  64. ii = ij + ik;
  65. }
  66. // CHECK-LABEL: define void @testintsub()
  67. void testintsub() {
  68. // CHECK: [[T1:%.*]] = load i32* @ij
  69. // CHECK-NEXT: [[T2:%.*]] = load i32* @ik
  70. // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]])
  71. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
  72. // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
  73. // CHECK: call void @__ubsan_handle_sub_overflow
  74. ii = ij - ik;
  75. }
  76. // CHECK-LABEL: define void @testintmul()
  77. void testintmul() {
  78. // CHECK: [[T1:%.*]] = load i32* @ij
  79. // CHECK-NEXT: [[T2:%.*]] = load i32* @ik
  80. // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]])
  81. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
  82. // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
  83. // CHECK: call void @__ubsan_handle_mul_overflow
  84. ii = ij * ik;
  85. }
  86. // CHECK-LABEL: define void @testintpostinc()
  87. void testintpostinc() {
  88. opaqueint(ii++);
  89. // CHECK: [[T1:%.*]] = load i32* @ii
  90. // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
  91. // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
  92. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
  93. // CHECK: call void @__ubsan_handle_add_overflow
  94. }
  95. // CHECK-LABEL: define void @testintpreinc()
  96. void testintpreinc() {
  97. opaqueint(++ii);
  98. // CHECK: [[T1:%.*]] = load i32* @ii
  99. // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1)
  100. // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
  101. // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
  102. // CHECK: call void @__ubsan_handle_add_overflow
  103. }