xref: /llvm-project/clang/test/Analysis/uninit-vals.c (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core -fblocks -verify -analyzer-output=text %s
2 
3 struct FPRec {
4   void (*my_func)(int * x);
5 };
6 
7 int bar(int x);
8 
f1_a(struct FPRec * foo)9 int f1_a(struct FPRec* foo) {
10   int x;
11   (*foo->my_func)(&x);
12   return bar(x)+1; // no-warning
13 }
14 
f1_b(void)15 int f1_b(void) {
16   int x; // expected-note{{'x' declared without an initial value}}
17   return bar(x)+1;  // expected-warning{{1st function call argument is an uninitialized value}}
18                     // expected-note@-1{{1st function call argument is an uninitialized value}}
19 }
20 
f2(void)21 int f2(void) {
22 
23   int x; // expected-note{{'x' declared without an initial value}}
24 
25   if (x+1)  // expected-warning{{The left operand of '+' is a garbage value}}
26             // expected-note@-1{{The left operand of '+' is a garbage value}}
27     return 1;
28 
29   return 2;
30 }
31 
f2_b(void)32 int f2_b(void) {
33   int x; // expected-note{{'x' declared without an initial value}}
34 
35   return ((1+x)+2+((x))) + 1 ? 1 : 2; // expected-warning{{The right operand of '+' is a garbage value}}
36                                       // expected-note@-1{{The right operand of '+' is a garbage value}}
37 }
38 
f3(void)39 int f3(void) {
40   int i; // expected-note{{'i' declared without an initial value}}
41   int *p = &i;
42   if (*p > 0) // expected-warning{{The left operand of '>' is a garbage value}}
43               // expected-note@-1{{The left operand of '>' is a garbage value}}
44     return 0;
45   else
46     return 1;
47 }
48 
49 void f4_aux(float* x);
f4(void)50 float f4(void) {
51   float x;
52   f4_aux(&x);
53   return x;  // no-warning
54 }
55 
56 struct f5_struct { int x; };
57 void f5_aux(struct f5_struct* s);
f5(void)58 int f5(void) {
59   struct f5_struct s;
60   f5_aux(&s);
61   return s.x; // no-warning
62 }
63 
f6(int x)64 void f6(int x) {
65   int a[20];
66   if (x == 25) {} // expected-note{{Assuming 'x' is equal to 25}}
67                   // expected-note@-1{{Taking true branch}}
68   if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
69                       // expected-note@-1{{The left operand of '==' is a garbage value due to array index out of bounds}}
70 }
71 
ret_uninit(void)72 int ret_uninit(void) {
73   int i; // expected-note{{'i' declared without an initial value}}
74   int *p = &i;
75   return *p;  // expected-warning{{Undefined or garbage value returned to caller}}
76               // expected-note@-1{{Undefined or garbage value returned to caller}}
77 }
78 
79 typedef unsigned char Boolean;
80 typedef const struct __CFNumber * CFNumberRef;
81 typedef signed long CFIndex;
82 typedef CFIndex CFNumberType;
83 typedef unsigned long UInt32;
84 typedef UInt32 CFStringEncoding;
85 typedef const struct __CFString * CFStringRef;
86 extern Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr);
87 extern CFStringRef CFStringConvertEncodingToIANACharSetName(CFStringEncoding encoding);
88 
rdar_6451816(CFNumberRef nr)89 CFStringRef rdar_6451816(CFNumberRef nr) {
90   CFStringEncoding encoding;
91   // &encoding is casted to void*.  This test case tests whether or not
92   // we properly invalidate the value of 'encoding'.
93   CFNumberGetValue(nr, 9, &encoding);
94   return CFStringConvertEncodingToIANACharSetName(encoding); // no-warning
95 }
96 
97 // PR 4630 - false warning with nonnull attribute
98 //  This false positive (due to a regression) caused the analyzer to falsely
99 //  flag a "return of uninitialized value" warning in the first branch due to
100 //  the nonnull attribute.
101 void pr_4630_aux(char *x, int *y) __attribute__ ((nonnull (1)));
102 void pr_4630_aux_2(char *x, int *y);
pr_4630(char * a,int y)103 int pr_4630(char *a, int y) {
104   int x;
105   if (y) {
106     pr_4630_aux(a, &x);
107     return x;   // no-warning
108   }
109   else {
110     pr_4630_aux_2(a, &x);
111     return x;   // no-warning
112   }
113 }
114 
115 // PR 4631 - False positive with union initializer
116 //  Previously the analyzer didn't examine the compound initializers of unions,
117 //  resulting in some false positives for initializers with side-effects.
118 union u_4631 { int a; };
119 struct s_4631 { int a; };
120 int pr4631_f2(int *p);
121 int pr4631_f3(void *q);
pr4631_f1(void)122 int pr4631_f1(void)
123 {
124   int x;
125   union u_4631 m = { pr4631_f2(&x) };
126   pr4631_f3(&m); // tell analyzer that we use m
127   return x;  // no-warning
128 }
pr4631_f1_b(void)129 int pr4631_f1_b(void)
130 {
131   int x;
132   struct s_4631 m = { pr4631_f2(&x) };
133   pr4631_f3(&m); // tell analyzer that we use m
134   return x;  // no-warning
135 }
136 
137 // FP when returning a void-valued expression from a void function...or block.
foo_radar12278788(void)138 void foo_radar12278788(void) { return; }
test_radar12278788(void)139 void test_radar12278788(void) {
140   return foo_radar12278788(); // no-warning
141 }
142 
foo_radar12278788_fp(void)143 void foo_radar12278788_fp(void) { return; }
144 typedef int (*RetIntFuncType)(void);
145 typedef void (*RetVoidFuncType)(void);
test_radar12278788_FP(void)146 int test_radar12278788_FP(void) {
147   RetVoidFuncType f = foo_radar12278788_fp;
148   return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
149                                 //expected-note@-1 {{Undefined or garbage value returned to caller}}
150 }
151 
rdar13665798(void)152 void rdar13665798(void) {
153   ^(void) {
154     return foo_radar12278788(); // no-warning
155   }();
156   ^void(void) {
157     return foo_radar12278788(); // no-warning
158   }();
159   ^int(void) { // expected-note{{Calling anonymous block}}
160     RetVoidFuncType f = foo_radar12278788_fp;
161     return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
162                                   //expected-note@-1 {{Undefined or garbage value returned to caller}}
163   }();
164 }
165 
166 struct Point {
167   int x, y;
168 };
169 
getHalfPoint(void)170 struct Point getHalfPoint(void) {
171   struct Point p;
172   p.x = 0;
173   return p;
174 }
175 
176 void use(struct Point p);
177 
testUseHalfPoint(void)178 void testUseHalfPoint(void) {
179   struct Point p = getHalfPoint(); // expected-note{{'p' initialized here}}
180   use(p); // expected-warning{{uninitialized}}
181           // expected-note@-1{{uninitialized}}
182 }
183 
testUseHalfPoint2(void)184 void testUseHalfPoint2(void) {
185   struct Point p;
186   p = getHalfPoint(); // expected-note{{Value assigned to 'p'}}
187   use(p); // expected-warning{{uninitialized}}
188           // expected-note@-1{{uninitialized}}
189 }
190