xref: /llvm-project/clang/test/Analysis/bstring_UninitRead.c (revision 483557224b8d36761f39d5847e17ef7361757f1b)
1 // RUN: %clang_analyze_cc1 -verify %s \
2 // RUN: -analyzer-checker=core,alpha.unix.cstring
3 
4 //===----------------------------------------------------------------------===//
5 // mempcpy() using character array. This is the easiest case, as memcpy
6 // intepretrs the dst and src buffers as character arrays (regardless of their
7 // actual type).
8 //===----------------------------------------------------------------------===//
9 
10 typedef typeof(sizeof(int)) size_t;
11 
12 void clang_analyzer_eval(int);
13 
14 void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
15 
memcpy_array_fully_uninit(char * dst)16 void memcpy_array_fully_uninit(char *dst) {
17   char buf[10];
18   memcpy(dst, buf, 10); // expected-warning{{The first element of the 2nd argument is undefined}}
19                         // expected-note@-1{{Other elements might also be undefined}}
20   (void)buf;
21 }
22 
memcpy_array_partially_uninit(char * dst)23 void memcpy_array_partially_uninit(char *dst) {
24   char buf[10];
25   buf[0] = 'i';
26   memcpy(dst, buf, 10); // expected-warning{{The last accessed element (at index 9) in the 2nd argument is undefined}}
27                         // expected-note@-1{{Other elements might also be undefined}}
28   (void)buf;
29 }
30 
memcpy_array_only_init_portion(char * dst)31 void memcpy_array_only_init_portion(char *dst) {
32   char buf[10];
33   buf[0] = 'i';
34   memcpy(dst, buf, 1);
35   (void)buf;
36 }
37 
memcpy_array_partially_init_error(char * dst)38 void memcpy_array_partially_init_error(char *dst) {
39   char buf[10];
40   buf[0] = 'i';
41   memcpy(dst, buf, 2); // expected-warning{{The last accessed element (at index 1) in the 2nd argument is undefined}}
42                       // expected-note@-1{{Other elements might also be undefined}}
43   (void)buf;
44 }
45 
46 // The interesting case here is that the portion we're copying is initialized,
47 // but not the whole matrix. We need to be careful to extract buf[1], and not
48 // buf when trying to peel region layers off from the source argument.
memcpy_array_from_matrix(char * dst)49 void memcpy_array_from_matrix(char *dst) {
50   char buf[2][2];
51   buf[1][0] = 'i';
52   buf[1][1] = 'j';
53   // FIXME: This is a FP -- we mistakenly retrieve the first element of buf,
54   // instead of the first element of buf[1]. getLValueElement simply peels off
55   // another ElementRegion layer, when in this case it really shouldn't.
56   memcpy(dst, buf[1], 2); // expected-warning{{The first element of the 2nd argument is undefined}}
57                           // expected-note@-1{{Other elements might also be undefined}}
58   (void)buf;
59 }
60 
61 //===----------------------------------------------------------------------===//
62 // mempcpy() using non-character arrays.
63 //===----------------------------------------------------------------------===//
64 
65 void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
66 
memcpy_int_array_fully_init()67 void memcpy_int_array_fully_init() {
68   int src[] = {1, 2, 3, 4};
69   int dst[5] = {0};
70   int *p;
71 
72   p = mempcpy(dst, src, 4 * sizeof(int));
73   clang_analyzer_eval(p == &dst[4]);
74 }
75 
memcpy_int_array_fully_init2(int * dest)76 void memcpy_int_array_fully_init2(int *dest) {
77   int t[] = {1, 2, 3};
78   memcpy(dest, t, sizeof(t));
79 }
80 
81 //===----------------------------------------------------------------------===//
82 // mempcpy() using nonarrays.
83 //===----------------------------------------------------------------------===//
84 
85 struct st {
86   int i;
87   int j;
88 };
89 
mempcpy_struct_partially_uninit()90 void mempcpy_struct_partially_uninit() {
91   struct st s1 = {0};
92   struct st s2;
93   struct st *p1;
94   struct st *p2;
95 
96   p1 = (&s2) + 1;
97 
98   // FIXME: Maybe ask UninitializedObjectChecker whether s1 is fully
99   // initialized?
100   p2 = mempcpy(&s2, &s1, sizeof(struct st));
101 
102   clang_analyzer_eval(p1 == p2);
103 }
104 
mempcpy_struct_fully_uninit()105 void mempcpy_struct_fully_uninit() {
106   struct st s1;
107   struct st s2;
108 
109   // FIXME: Maybe ask UninitializedObjectChecker whether s1 is fully
110   // initialized?
111   mempcpy(&s2, &s1, sizeof(struct st));
112 }
113 
114 // Creduced crash. In this case, an symbolicregion is wrapped in an
115 // elementregion for the src argument.
116 void *ga_copy_strings_from_0;
117 void *memmove();
118 void alloc();
ga_copy_strings()119 void ga_copy_strings() {
120   int i = 0;
121   for (;; ++i)
122     memmove(alloc, ((char **)ga_copy_strings_from_0)[i], 1);
123 }
124 
125 // Creduced crash. In this case, retrieving the Loc for the first element failed.
126 char mov_mdhd_language_map[][4] = {};
127 int ff_mov_lang_to_iso639_code;
128 char *ff_mov_lang_to_iso639_to;
ff_mov_lang_to_iso639()129 void ff_mov_lang_to_iso639() {
130   memcpy(ff_mov_lang_to_iso639_to,
131          mov_mdhd_language_map[ff_mov_lang_to_iso639_code], 4);
132 }
133