|  | // RUN: %clang_analyze_cc1 -std=c++20 \ | 
|  | // RUN:  -analyzer-checker=core,unix,cplusplus,debug.ExprInspection \ | 
|  | // RUN:  -triple x86_64-unknown-linux-gnu \ | 
|  | // RUN:  -verify %s | 
|  |  | 
|  | #include "Inputs/system-header-simulator-cxx.h" | 
|  |  | 
|  | typedef __SIZE_TYPE__ size_t; | 
|  | void *malloc(size_t); | 
|  | void *alloca(size_t); | 
|  | void *realloc(void *ptr, size_t size); | 
|  | void *calloc(size_t number, size_t size); | 
|  | void free(void *); | 
|  |  | 
|  | struct S { | 
|  | int f; | 
|  | }; | 
|  |  | 
|  | void clang_analyzer_dump(int); | 
|  | void clang_analyzer_dump(const void *); | 
|  | void clang_analyzer_dumpExtent(int); | 
|  | void clang_analyzer_dumpExtent(const void *); | 
|  | void clang_analyzer_dumpElementCount(int); | 
|  | void clang_analyzer_dumpElementCount(const void *); | 
|  |  | 
|  | int clang_analyzer_getExtent(void *); | 
|  | void clang_analyzer_eval(bool); | 
|  |  | 
|  | void var_simple_ref() { | 
|  | int a = 13; | 
|  | clang_analyzer_dump(&a);             // expected-warning {{a}} | 
|  | clang_analyzer_dumpExtent(&a);       // expected-warning {{4 S64b}} | 
|  | clang_analyzer_dumpElementCount(&a); // expected-warning {{1 S64b}} | 
|  | } | 
|  |  | 
|  | void var_simple_ptr(int *a) { | 
|  | clang_analyzer_dump(a);             // expected-warning {{SymRegion{reg_$1<int * a>}}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{extent_$2{SymRegion{reg_$1<int * a>}}}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{(extent_$2{SymRegion{reg_$1<int * a>}}) / 4}} | 
|  | } | 
|  |  | 
|  | void var_array() { | 
|  | int a[] = {1, 2, 3}; | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{a,0 S64b,int}}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}} | 
|  | } | 
|  |  | 
|  | void string() { | 
|  | clang_analyzer_dump("foo");             // expected-warning {{Element{"foo",0 S64b,char}}} | 
|  | clang_analyzer_dumpExtent("foo");       // expected-warning {{4 S64b}} | 
|  | clang_analyzer_dumpElementCount("foo"); // expected-warning {{4 S64b}} | 
|  | } | 
|  |  | 
|  | void struct_simple_ptr(S *a) { | 
|  | clang_analyzer_dump(a);             // expected-warning {{SymRegion{reg_$1<S * a>}}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{extent_$2{SymRegion{reg_$1<S * a>}}}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{(extent_$2{SymRegion{reg_$1<S * a>}}) / 4}} | 
|  | } | 
|  |  | 
|  | void field_ref(S a) { | 
|  | clang_analyzer_dump(&a.f);             // expected-warning {{a.f}} | 
|  | clang_analyzer_dumpExtent(&a.f);       // expected-warning {{4 S64b}} | 
|  | clang_analyzer_dumpElementCount(&a.f); // expected-warning {{1 S64b}} | 
|  | } | 
|  |  | 
|  | void field_ptr(S *a) { | 
|  | clang_analyzer_dump(&a->f);             // expected-warning {{Element{SymRegion{reg_$1<S * a>},0 S64b,struct S}.f}} | 
|  | clang_analyzer_dumpExtent(&a->f);       // expected-warning {{extent_$2{SymRegion{reg_$1<S * a>}}}} | 
|  | clang_analyzer_dumpElementCount(&a->f); // expected-warning {{(extent_$2{SymRegion{reg_$1<S * a>}}) / 4U}} | 
|  | } | 
|  |  | 
|  | void symbolic_array() { | 
|  | int *a = new int[3]; | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}} | 
|  | delete[] a; | 
|  | } | 
|  |  | 
|  | void symbolic_placement_new() { | 
|  | char *buf = new char[sizeof(int) * 3]; | 
|  | int *a = new (buf) int(12); | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}} | 
|  | delete[] buf; | 
|  | } | 
|  |  | 
|  | void symbolic_malloc() { | 
|  | int *a = (int *)malloc(12); | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}} | 
|  | free(a); | 
|  | } | 
|  |  | 
|  | void symbolic_alloca() { | 
|  | int *a = (int *)alloca(12); | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{alloca{}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{12 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{3 S64b}} | 
|  | } | 
|  |  | 
|  | void symbolic_complex() { | 
|  | int *a = (int *)malloc(4); | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{4 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{1 S64b}} | 
|  |  | 
|  | int *b = (int *)realloc(a, sizeof(int) * 2); | 
|  | clang_analyzer_dumpExtent(b);       // expected-warning {{8 S64b}} | 
|  | clang_analyzer_dumpElementCount(b); // expected-warning {{2 S64b}} | 
|  | free(b); | 
|  |  | 
|  | int *c = (int *)calloc(3, 4); | 
|  | clang_analyzer_dumpExtent(c);       // expected-warning {{12 S64b}} | 
|  | clang_analyzer_dumpElementCount(c); // expected-warning {{3 S64b}} | 
|  | free(c); | 
|  | } | 
|  |  | 
|  | void signedness_equality() { | 
|  | char *a = new char[sizeof(char) * 13]; | 
|  | char *b = (char *)malloc(13); | 
|  |  | 
|  | clang_analyzer_dump(clang_analyzer_getExtent(a)); // expected-warning {{13 S64b}} | 
|  | clang_analyzer_dump(clang_analyzer_getExtent(b)); // expected-warning {{13 S64b}} | 
|  | clang_analyzer_eval(clang_analyzer_getExtent(a) == | 
|  | clang_analyzer_getExtent(b)); | 
|  | // expected-warning@-2 {{TRUE}} | 
|  |  | 
|  | delete[] a; | 
|  | free(b); | 
|  | } | 
|  |  | 
|  | void default_new_aligned() { | 
|  | struct alignas(32) S {}; | 
|  |  | 
|  | S *a = new S[10]; | 
|  |  | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{HeapSymRegion{conj}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{320 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{10 S64b}} | 
|  |  | 
|  | delete[] a; | 
|  | } | 
|  |  | 
|  | void *operator new[](std::size_t, std::align_val_t, bool hack) throw(); | 
|  |  | 
|  | void user_defined_new() { | 
|  | int *a = new (std::align_val_t(32), true) int[10]; | 
|  |  | 
|  | clang_analyzer_dump(a);             // expected-warning {{Element{SymRegion{conj}} | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning-re {{{{^extent_\$[0-9]\{SymRegion{conj}}}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning-re {{{{^\(extent_\$[0-9]\{SymRegion{conj.*\) / 4}}}} | 
|  |  | 
|  | operator delete[](a, std::align_val_t(32)); | 
|  | } | 
|  |  | 
|  | int a[5][0]; | 
|  | struct T { | 
|  | int x[]; | 
|  | }; | 
|  |  | 
|  | T t[5]; | 
|  | void zero_sized_element() { | 
|  | clang_analyzer_dumpExtent(a);       // expected-warning {{0 S64b}} | 
|  | clang_analyzer_dumpElementCount(a); // expected-warning {{5 S64b}} | 
|  | clang_analyzer_dumpExtent(t);       // expected-warning {{0 S64b}} | 
|  | clang_analyzer_dumpElementCount(t); // expected-warning {{5 S64b}} | 
|  | } | 
|  |  | 
|  | void extent_with_offset() { | 
|  | int nums[] = {1,2,3}; | 
|  | char *p = (char*)&nums[1]; | 
|  |  | 
|  | clang_analyzer_dumpExtent(p);         // expected-warning {{8 S64b}} | 
|  | clang_analyzer_dumpElementCount(p);   // expected-warning {{8 S64b}} | 
|  | ++p; | 
|  | clang_analyzer_dumpExtent(p);         // expected-warning {{7 S64b}} | 
|  | clang_analyzer_dumpElementCount(p);   // expected-warning {{7 S64b}} | 
|  | ++p; | 
|  | int *q = (int*)p; | 
|  | clang_analyzer_dumpExtent(q);         // expected-warning {{6 S64b}} | 
|  | clang_analyzer_dumpElementCount(q);   // expected-warning {{1 S64b}} | 
|  | } |