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 8extern unsigned UnsignedErrorCode; 9extern unsigned long UnsignedLongErrorCode; 10extern unsigned long long UnsignedLongLongErrorCode; 11extern int IntErrorCode; 12extern long LongErrorCode; 13extern long long LongLongErrorCode; 14 15unsigned 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 24unsigned 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 33unsigned 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 42unsigned 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 51unsigned 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 60unsigned 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 69unsigned 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 78unsigned 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 87unsigned 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 96int 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 105long 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 114long 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 123int 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 132long 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 141long 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 150int 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 159long 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 168long 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