1 // RUN: %clang_analyze_cc1 -std=c++20 \
2 // RUN:  -analyzer-checker=core,unix,cplusplus,debug.ExprInspection \
3 // RUN:  -triple x86_64-unknown-linux-gnu \
4 // RUN:  -verify %s
5 
6 #include "Inputs/system-header-simulator-cxx.h"
7 
8 typedef __SIZE_TYPE__ size_t;
9 void *malloc(size_t);
10 void *alloca(size_t);
11 void *realloc(void *ptr, size_t size);
12 void *calloc(size_t number, size_t size);
13 void free(void *);
14 
15 struct S {
16   int f;
17 };
18 
19 void clang_analyzer_dump(int);
20 void clang_analyzer_dump(const void *);
21 void clang_analyzer_dumpExtent(int);
22 void clang_analyzer_dumpExtent(const void *);
23 void clang_analyzer_dumpElementCount(int);
24 void clang_analyzer_dumpElementCount(const void *);
25 
26 int clang_analyzer_getExtent(void *);
27 void clang_analyzer_eval(bool);
28 
var_simple_ref()29 void var_simple_ref() {
30   int a = 13;
31   clang_analyzer_dump(&a);             // expected-warning {{a}}
32   clang_analyzer_dumpExtent(&a);       // expected-warning {{4 S64b}}
33   clang_analyzer_dumpElementCount(&a); // expected-warning {{1 S64b}}
34 }
35 
var_simple_ptr(int * a)36 void var_simple_ptr(int *a) {
37   clang_analyzer_dump(a);             // expected-warning {{SymRegion{reg_$0<int * a>}}}
38   clang_analyzer_dumpExtent(a);       // expected-warning {{extent_$1{SymRegion{reg_$0<int * a>}}}}
39   clang_analyzer_dumpElementCount(a); // expected-warning {{(extent_$1{SymRegion{reg_$0<int * a>}}) / 4}}
40 }
41 
var_array()42 void var_array() {
43   int a[] = {1, 2, 3};
44   clang_analyzer_dump(a);             // expected-warning {{Element{a,0 S64b,int}}}
45   clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}}
46   clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}}
47 }
48 
string()49 void string() {
50   clang_analyzer_dump("foo");             // expected-warning {{Element{"foo",0 S64b,char}}}
51   clang_analyzer_dumpExtent("foo");       // expected-warning {{4 S64b}}
52   clang_analyzer_dumpElementCount("foo"); // expected-warning {{4 S64b}}
53 }
54 
struct_simple_ptr(S * a)55 void struct_simple_ptr(S *a) {
56   clang_analyzer_dump(a);             // expected-warning {{SymRegion{reg_$0<struct S * a>}}}
57   clang_analyzer_dumpExtent(a);       // expected-warning {{extent_$1{SymRegion{reg_$0<struct S * a>}}}}
58   clang_analyzer_dumpElementCount(a); // expected-warning {{(extent_$1{SymRegion{reg_$0<struct S * a>}}) / 4}}
59 }
60 
field_ref(S a)61 void field_ref(S a) {
62   clang_analyzer_dump(&a.f);             // expected-warning {{a.f}}
63   clang_analyzer_dumpExtent(&a.f);       // expected-warning {{4 S64b}}
64   clang_analyzer_dumpElementCount(&a.f); // expected-warning {{1 S64b}}
65 }
66 
field_ptr(S * a)67 void field_ptr(S *a) {
68   clang_analyzer_dump(&a->f);             // expected-warning {{SymRegion{reg_$0<struct S * a>}.f}}
69   clang_analyzer_dumpExtent(&a->f);       // expected-warning {{4 S64b}}
70   clang_analyzer_dumpElementCount(&a->f); // expected-warning {{1 S64b}}
71 }
72 
symbolic_array()73 void symbolic_array() {
74   int *a = new int[3];
75   clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}}
76   clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}}
77   clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}}
78   delete[] a;
79 }
80 
symbolic_placement_new()81 void symbolic_placement_new() {
82   char *buf = new char[sizeof(int) * 3];
83   int *a = new (buf) int(12);
84   clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}}
85   clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}}
86   clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}}
87   delete[] buf;
88 }
89 
symbolic_malloc()90 void symbolic_malloc() {
91   int *a = (int *)malloc(12);
92   clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}}
93   clang_analyzer_dumpExtent(a);       // expected-warning {{12 U64b}}
94   clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}}
95   free(a);
96 }
97 
symbolic_alloca()98 void symbolic_alloca() {
99   int *a = (int *)alloca(12);
100   clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}}
101   clang_analyzer_dumpExtent(a);       // expected-warning {{12 U64b}}
102   clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}}
103 }
104 
symbolic_complex()105 void symbolic_complex() {
106   int *a = (int *)malloc(4);
107   clang_analyzer_dumpExtent(a);       // expected-warning {{4 U64b}}
108   clang_analyzer_dumpElementCount(a); // expected-warning {{1 S64b}}
109 
110   int *b = (int *)realloc(a, sizeof(int) * 2);
111   clang_analyzer_dumpExtent(b);       // expected-warning {{8 U64b}}
112   clang_analyzer_dumpElementCount(b); // expected-warning {{2 S64b}}
113   free(b);
114 
115   int *c = (int *)calloc(3, 4);
116   clang_analyzer_dumpExtent(c);       // expected-warning {{12 U64b}}
117   clang_analyzer_dumpElementCount(c); // expected-warning {{3 S64b}}
118   free(c);
119 }
120 
signedness_equality()121 void signedness_equality() {
122   char *a = new char[sizeof(char) * 13];
123   char *b = (char *)malloc(13);
124 
125   clang_analyzer_dump(clang_analyzer_getExtent(a)); // expected-warning {{13 S64b}}
126   clang_analyzer_dump(clang_analyzer_getExtent(b)); // expected-warning {{13 U64b}}
127   clang_analyzer_eval(clang_analyzer_getExtent(a) ==
128                       clang_analyzer_getExtent(b));
129   // expected-warning@-2 {{TRUE}}
130 
131   delete[] a;
132   free(b);
133 }
134 
default_new_aligned()135 void default_new_aligned() {
136   struct alignas(32) S {};
137 
138   S *a = new S[10];
139 
140   clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}}
141   clang_analyzer_dumpExtent(a);       // expected-warning {{320 S64b}}
142   clang_analyzer_dumpElementCount(a); // expected-warning {{10 S64b}}
143 
144   delete[] a;
145 }
146 
147 void *operator new[](std::size_t, std::align_val_t, bool hack) throw();
148 
user_defined_new()149 void user_defined_new() {
150   int *a = new (std::align_val_t(32), true) int[10];
151 
152   clang_analyzer_dump(a);             // expected-warning {{Element{SymRegion{conj}}
153   clang_analyzer_dumpExtent(a);       // expected-warning-re {{{{^extent_\$[0-9]\{SymRegion{conj}}}}
154   clang_analyzer_dumpElementCount(a); // expected-warning-re {{{{^\(extent_\$[0-9]\{SymRegion{conj.*\) / 4}}}}
155 
156   operator delete[](a, std::align_val_t(32));
157 }
158