Clang Project

clang_source_code/test/CodeGen/integer-overflow.c
1// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
2// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV
3// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
4// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CATCH_UB
5// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER
6
7
8// Tests for signed integer overflow stuff.
9// rdar://7432000 rdar://7221421
10void test1() {
11  // DEFAULT-LABEL: define void @test1
12  // WRAPV-LABEL: define void @test1
13  // TRAPV-LABEL: define void @test1
14  extern volatile int f11G, a, b;
15  
16  // DEFAULT: add nsw i32
17  // WRAPV: add i32
18  // TRAPV: llvm.sadd.with.overflow.i32
19  // CATCH_UB: llvm.sadd.with.overflow.i32
20  // TRAPV_HANDLER: foo(
21  f11G = a + b;
22  
23  // DEFAULT: sub nsw i32
24  // WRAPV: sub i32
25  // TRAPV: llvm.ssub.with.overflow.i32
26  // CATCH_UB: llvm.ssub.with.overflow.i32
27  // TRAPV_HANDLER: foo(
28  f11G = a - b;
29  
30  // DEFAULT: mul nsw i32
31  // WRAPV: mul i32
32  // TRAPV: llvm.smul.with.overflow.i32
33  // CATCH_UB: llvm.smul.with.overflow.i32
34  // TRAPV_HANDLER: foo(
35  f11G = a * b;
36
37  // DEFAULT: sub nsw i32 0, 
38  // WRAPV: sub i32 0, 
39  // TRAPV: llvm.ssub.with.overflow.i32(i32 0
40  // CATCH_UB: llvm.ssub.with.overflow.i32(i32 0
41  // TRAPV_HANDLER: foo(
42  f11G = -a;
43  
44  // PR7426 - Overflow checking for increments.
45  
46  // DEFAULT: add nsw i32 {{.*}}, 1
47  // WRAPV: add i32 {{.*}}, 1
48  // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 1)
49  // CATCH_UB: llvm.sadd.with.overflow.i32({{.*}}, i32 1)
50  // TRAPV_HANDLER: foo(
51  ++a;
52  
53  // DEFAULT: add nsw i32 {{.*}}, -1
54  // WRAPV: add i32 {{.*}}, -1
55  // TRAPV: llvm.ssub.with.overflow.i32({{.*}}, i32 1)
56  // CATCH_UB: llvm.ssub.with.overflow.i32({{.*}}, i32 1)
57  // TRAPV_HANDLER: foo(
58  --a;
59  
60  // -fwrapv should turn off inbounds for GEP's, PR9256
61  extern int* P;
62  ++P;
63  // DEFAULT: getelementptr inbounds i32, i32*
64  // WRAPV: getelementptr i32, i32*
65  // TRAPV: getelementptr inbounds i32, i32*
66  // CATCH_UB: getelementptr inbounds i32, i32*
67
68  // PR9350: char pre-increment never overflows.
69  extern volatile signed char PR9350_char_inc;
70  // DEFAULT: add i8 {{.*}}, 1
71  // WRAPV: add i8 {{.*}}, 1
72  // TRAPV: add i8 {{.*}}, 1
73  // CATCH_UB: add i8 {{.*}}, 1
74  ++PR9350_char_inc;
75
76  // PR9350: char pre-decrement never overflows.
77  extern volatile signed char PR9350_char_dec;
78  // DEFAULT: add i8 {{.*}}, -1
79  // WRAPV: add i8 {{.*}}, -1
80  // TRAPV: add i8 {{.*}}, -1
81  // CATCH_UB: add i8 {{.*}}, -1
82  --PR9350_char_dec;
83
84  // PR9350: short pre-increment never overflows.
85  extern volatile signed short PR9350_short_inc;
86  // DEFAULT: add i16 {{.*}}, 1
87  // WRAPV: add i16 {{.*}}, 1
88  // TRAPV: add i16 {{.*}}, 1
89  // CATCH_UB: add i16 {{.*}}, 1
90  ++PR9350_short_inc;
91
92  // PR9350: short pre-decrement never overflows.
93  extern volatile signed short PR9350_short_dec;
94  // DEFAULT: add i16 {{.*}}, -1
95  // WRAPV: add i16 {{.*}}, -1
96  // TRAPV: add i16 {{.*}}, -1
97  // CATCH_UB: add i16 {{.*}}, -1
98  --PR9350_short_dec;
99
100  // PR24256: don't instrument __builtin_frame_address.
101  __builtin_frame_address(0 + 0);
102  // DEFAULT:  call i8* @llvm.frameaddress(i32 0)
103  // WRAPV:    call i8* @llvm.frameaddress(i32 0)
104  // TRAPV:    call i8* @llvm.frameaddress(i32 0)
105  // CATCH_UB: call i8* @llvm.frameaddress(i32 0)
106}
107