Home | History | Annotate | Download | only in CodeGen
      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