1 // Test CodeGen for Security Check Overflow Builtins. 2 // rdar://13421498 3 4 // RUN: %clang_cc1 -triple "i686-unknown-unknown" -emit-llvm -x c %s -o - -O0 | FileCheck %s 5 // RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - -O0 | FileCheck %s 6 // RUN: %clang_cc1 -triple "x86_64-mingw32" -emit-llvm -x c %s -o - -O0 | FileCheck %s 7 8 extern unsigned UnsignedErrorCode; 9 extern unsigned long UnsignedLongErrorCode; 10 extern unsigned long long UnsignedLongLongErrorCode; 11 extern int IntErrorCode; 12 extern long LongErrorCode; 13 extern long long LongLongErrorCode; 14 15 unsigned test_uadd_overflow(unsigned x, unsigned y) { 16 // CHECK: @test_uadd_overflow 17 // CHECK: %{{.+}} = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}}) 18 unsigned result; 19 if (__builtin_uadd_overflow(x, y, &result)) 20 return UnsignedErrorCode; 21 return result; 22 } 23 24 unsigned long test_uaddl_overflow(unsigned long x, unsigned long y) { 25 // CHECK: @test_uaddl_overflow([[UL:i32|i64]] %x 26 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}}) 27 unsigned long result; 28 if (__builtin_uaddl_overflow(x, y, &result)) 29 return UnsignedLongErrorCode; 30 return result; 31 } 32 33 unsigned long long test_uaddll_overflow(unsigned long long x, unsigned long long y) { 34 // CHECK: @test_uaddll_overflow 35 // CHECK: %{{.+}} = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}}) 36 unsigned long long result; 37 if (__builtin_uaddll_overflow(x, y, &result)) 38 return UnsignedLongLongErrorCode; 39 return result; 40 } 41 42 unsigned test_usub_overflow(unsigned x, unsigned y) { 43 // CHECK: @test_usub_overflow 44 // CHECK: %{{.+}} = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}}) 45 unsigned result; 46 if (__builtin_usub_overflow(x, y, &result)) 47 return UnsignedErrorCode; 48 return result; 49 } 50 51 unsigned long test_usubl_overflow(unsigned long x, unsigned long y) { 52 // CHECK: @test_usubl_overflow([[UL:i32|i64]] %x 53 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}}) 54 unsigned long result; 55 if (__builtin_usubl_overflow(x, y, &result)) 56 return UnsignedLongErrorCode; 57 return result; 58 } 59 60 unsigned long long test_usubll_overflow(unsigned long long x, unsigned long long y) { 61 // CHECK: @test_usubll_overflow 62 // CHECK: %{{.+}} = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}}) 63 unsigned long long result; 64 if (__builtin_usubll_overflow(x, y, &result)) 65 return UnsignedLongLongErrorCode; 66 return result; 67 } 68 69 unsigned test_umul_overflow(unsigned x, unsigned y) { 70 // CHECK: @test_umul_overflow 71 // CHECK: %{{.+}} = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}}) 72 unsigned result; 73 if (__builtin_umul_overflow(x, y, &result)) 74 return UnsignedErrorCode; 75 return result; 76 } 77 78 unsigned long test_umull_overflow(unsigned long x, unsigned long y) { 79 // CHECK: @test_umull_overflow([[UL:i32|i64]] %x 80 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.umul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}}) 81 unsigned long result; 82 if (__builtin_umull_overflow(x, y, &result)) 83 return UnsignedLongErrorCode; 84 return result; 85 } 86 87 unsigned long long test_umulll_overflow(unsigned long long x, unsigned long long y) { 88 // CHECK: @test_umulll_overflow 89 // CHECK: %{{.+}} = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}}) 90 unsigned long long result; 91 if (__builtin_umulll_overflow(x, y, &result)) 92 return UnsignedLongLongErrorCode; 93 return result; 94 } 95 96 int test_sadd_overflow(int x, int y) { 97 // CHECK: @test_sadd_overflow 98 // CHECK: %{{.+}} = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}}) 99 int result; 100 if (__builtin_sadd_overflow(x, y, &result)) 101 return IntErrorCode; 102 return result; 103 } 104 105 long test_saddl_overflow(long x, long y) { 106 // CHECK: @test_saddl_overflow([[UL:i32|i64]] %x 107 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.sadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}}) 108 long result; 109 if (__builtin_saddl_overflow(x, y, &result)) 110 return LongErrorCode; 111 return result; 112 } 113 114 long long test_saddll_overflow(long long x, long long y) { 115 // CHECK: @test_saddll_overflow 116 // CHECK: %{{.+}} = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}}) 117 long long result; 118 if (__builtin_saddll_overflow(x, y, &result)) 119 return LongLongErrorCode; 120 return result; 121 } 122 123 int test_ssub_overflow(int x, int y) { 124 // CHECK: @test_ssub_overflow 125 // CHECK: %{{.+}} = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}}) 126 int result; 127 if (__builtin_ssub_overflow(x, y, &result)) 128 return IntErrorCode; 129 return result; 130 } 131 132 long test_ssubl_overflow(long x, long y) { 133 // CHECK: @test_ssubl_overflow([[UL:i32|i64]] %x 134 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.ssub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}}) 135 long result; 136 if (__builtin_ssubl_overflow(x, y, &result)) 137 return LongErrorCode; 138 return result; 139 } 140 141 long long test_ssubll_overflow(long long x, long long y) { 142 // CHECK: @test_ssubll_overflow 143 // CHECK: %{{.+}} = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}}) 144 long long result; 145 if (__builtin_ssubll_overflow(x, y, &result)) 146 return LongLongErrorCode; 147 return result; 148 } 149 150 int test_smul_overflow(int x, int y) { 151 // CHECK: @test_smul_overflow 152 // CHECK: %{{.+}} = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}}) 153 int result; 154 if (__builtin_smul_overflow(x, y, &result)) 155 return IntErrorCode; 156 return result; 157 } 158 159 long test_smull_overflow(long x, long y) { 160 // CHECK: @test_smull_overflow([[UL:i32|i64]] %x 161 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.smul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}}) 162 long result; 163 if (__builtin_smull_overflow(x, y, &result)) 164 return LongErrorCode; 165 return result; 166 } 167 168 long long test_smulll_overflow(long long x, long long y) { 169 // CHECK: @test_smulll_overflow 170 // CHECK: %{{.+}} = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}}) 171 long long result; 172 if (__builtin_smulll_overflow(x, y, &result)) 173 return LongLongErrorCode; 174 return result; 175 } 176