2015-09-25 00:52:56 +08:00
// Given code 'struct aa { char s1[4]; char * s2;} a; memcpy(a.s1, ...);',
// this test checks that the CStringChecker only invalidates the destination buffer array a.s1 (instead of a.s1 and a.s2).
// At the moment the whole of the destination array content is invalidated.
// If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated.
// Specific triple set to test structures of size 0.
2022-06-14 15:20:41 +08:00
// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
2015-09-25 00:52:56 +08:00
typedef __typeof ( sizeof ( int ) ) size_t ;
char * strdup ( const char * s ) ;
void free ( void * ) ;
void * memcpy ( void * dst , const void * src , size_t n ) ; // expected-note{{passing argument to parameter 'dst' here}}
void * malloc ( size_t n ) ;
void clang_analyzer_eval ( int ) ;
struct aa {
char s1 [ 4 ] ;
char * s2 ;
} ;
// Test different types of structure initialisation.
2022-02-13 21:02:46 +08:00
int f0 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a0 = { { 1 , 2 , 3 , 4 } , 0 } ;
a0 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a0 . s1 , input , 4 ) ;
clang_analyzer_eval ( a0 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a0 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a0 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a0 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a0 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( a0 . s2 ) ; // no warning
return 0 ;
}
2022-02-13 21:02:46 +08:00
int f1 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a1 ;
a1 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a1 . s1 , input , 4 ) ;
clang_analyzer_eval ( a1 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a1 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a1 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a1 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a1 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( a1 . s2 ) ; // no warning
return 0 ;
}
2022-02-13 21:02:46 +08:00
int f2 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a2 = { { 1 , 2 } } ;
a2 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a2 . s1 , input , 4 ) ;
clang_analyzer_eval ( a2 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a2 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a2 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a2 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a2 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( a2 . s2 ) ; // no warning
return 0 ;
}
2022-02-13 21:02:46 +08:00
int f3 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a3 = { { 1 , 2 , 3 , 4 } , 0 } ;
a3 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
int * dest = ( int * ) a3 . s1 ;
memcpy ( dest , input , 4 ) ;
clang_analyzer_eval ( a3 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a3 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a3 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a3 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a3 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( a3 . s2 ) ; // no warning
return 0 ;
}
struct bb {
struct aa a ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f4 ( void ) {
2015-09-25 00:52:56 +08:00
struct bb b0 = { { 1 , 2 , 3 , 4 } , 0 } ;
b0 . s2 = strdup ( " hello " ) ;
b0 . a . s2 = strdup ( " hola " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
char * dest = ( char * ) ( b0 . a . s1 ) ;
memcpy ( dest , input , 4 ) ;
clang_analyzer_eval ( b0 . a . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( b0 . a . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( b0 . a . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( b0 . a . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( dest [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( b0 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( b0 . a . s2 ) ; // no warning
free ( b0 . s2 ) ; // no warning
return 0 ;
}
// Test that memory leaks are caught.
2022-02-13 21:02:46 +08:00
int f5 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a0 = { { 1 , 2 , 3 , 4 } , 0 } ;
a0 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a0 . s1 , input , 4 ) ;
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'a0.s2'}}
}
2022-02-13 21:02:46 +08:00
int f6 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a1 ;
a1 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a1 . s1 , input , 4 ) ;
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'a1.s2'}}
}
2022-02-13 21:02:46 +08:00
int f7 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a2 = { { 1 , 2 } } ;
a2 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a2 . s1 , input , 4 ) ;
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'a2.s2'}}
}
2022-02-13 21:02:46 +08:00
int f8 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a3 = { { 1 , 2 , 3 , 4 } , 0 } ;
a3 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
int * dest = ( int * ) a3 . s1 ;
memcpy ( dest , input , 4 ) ;
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'a3.s2'}}
}
2022-02-13 21:02:46 +08:00
int f9 ( void ) {
2015-09-25 00:52:56 +08:00
struct bb b0 = { { 1 , 2 , 3 , 4 } , 0 } ;
b0 . s2 = strdup ( " hello " ) ;
b0 . a . s2 = strdup ( " hola " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
char * dest = ( char * ) ( b0 . a . s1 ) ;
memcpy ( dest , input , 4 ) ;
free ( b0 . a . s2 ) ; // expected-warning{{Potential leak of memory pointed to by 'b0.s2'}}
return 0 ;
}
2022-02-13 21:02:46 +08:00
int f10 ( void ) {
2015-09-25 00:52:56 +08:00
struct bb b0 = { { 1 , 2 , 3 , 4 } , 0 } ;
b0 . s2 = strdup ( " hello " ) ;
b0 . a . s2 = strdup ( " hola " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
char * dest = ( char * ) ( b0 . a . s1 ) ;
memcpy ( dest , input , 4 ) ;
free ( b0 . s2 ) ; // expected-warning{{Potential leak of memory pointed to by 'b0.a.s2'}}
return 0 ;
}
// Test invalidating fields being addresses of array.
struct cc {
char * s1 ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f11 ( void ) {
2015-09-25 00:52:56 +08:00
char x [ 4 ] = { 1 , 2 } ;
x [ 0 ] = 1 ;
x [ 1 ] = 2 ;
struct cc c0 ;
c0 . s2 = strdup ( " hello " ) ;
c0 . s1 = & x [ 0 ] ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( c0 . s1 , input , 4 ) ;
clang_analyzer_eval ( x [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( x [ 1 ] = = 2 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( c0 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( c0 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( c0 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( c0 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
free ( c0 . s2 ) ; // no-warning
return 0 ;
}
// Test inverting field position between s1 and s2.
struct dd {
char * s2 ;
char s1 [ 4 ] ;
} ;
2022-02-13 21:02:46 +08:00
int f12 ( void ) {
2015-09-25 00:52:56 +08:00
struct dd d0 = { 0 , { 1 , 2 , 3 , 4 } } ;
d0 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( d0 . s1 , input , 4 ) ;
clang_analyzer_eval ( d0 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d0 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d0 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d0 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d0 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( d0 . s2 ) ; // no warning
return 0 ;
}
// Test arrays of structs.
struct ee {
int a ;
char b ;
} ;
struct EE {
struct ee s1 [ 2 ] ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f13 ( void ) {
2015-09-25 00:52:56 +08:00
struct EE E0 = { { { 1 , 2 } , { 3 , 4 } } , 0 } ;
E0 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( E0 . s1 , input , 4 ) ;
clang_analyzer_eval ( E0 . s1 [ 0 ] . a = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( E0 . s1 [ 0 ] . b = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( E0 . s1 [ 1 ] . a = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( E0 . s1 [ 1 ] . b = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( E0 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( E0 . s2 ) ; // no warning
return 0 ;
}
// Test global parameters.
struct aa a15 = { { 1 , 2 , 3 , 4 } , 0 } ;
2022-02-13 21:02:46 +08:00
int f15 ( void ) {
2015-09-25 00:52:56 +08:00
a15 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a15 . s1 , input , 4 ) ;
clang_analyzer_eval ( a15 . s1 [ 0 ] = = ' a ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a15 . s1 [ 1 ] = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a15 . s1 [ 2 ] = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a15 . s1 [ 3 ] = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a15 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( a15 . s2 ) ; // no warning
return 0 ;
}
// Test array of 0 sized elements.
struct empty { } ;
struct gg {
struct empty s1 [ 4 ] ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f16 ( void ) {
2015-09-25 00:52:56 +08:00
struct gg g0 = { { } , 0 } ;
g0 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( g0 . s1 , input , 4 ) ;
clang_analyzer_eval ( * ( int * ) ( & g0 . s1 [ 0 ] ) = = ' a ' ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' g0 . s2 ' } }
clang_analyzer_eval ( * ( int * ) ( & g0 . s1 [ 1 ] ) = = ' b ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( * ( int * ) ( & g0 . s1 [ 2 ] ) = = ' c ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( * ( int * ) ( & g0 . s1 [ 3 ] ) = = ' d ' ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( g0 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( g0 . s2 ) ; // no warning
return 0 ;
}
// Test array of 0 elements.
struct hh {
char s1 [ 0 ] ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f17 ( void ) {
2015-09-25 00:52:56 +08:00
struct hh h0 ;
h0 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( h0 . s1 , input , 4 ) ;
clang_analyzer_eval ( h0 . s1 [ 0 ] = = ' a ' ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' h0 . s2 ' } }
clang_analyzer_eval ( h0 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
free ( h0 . s2 ) ; // no warning
return 0 ;
}
// Test writing past the array.
struct ii {
char s1 [ 4 ] ;
int i ;
int j ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f18 ( void ) {
2015-09-25 00:52:56 +08:00
struct ii i18 = { { 1 , 2 , 3 , 4 } , 5 , 6 } ;
i18 . i = 10 ;
i18 . j = 11 ;
i18 . s2 = strdup ( " hello " ) ;
char input [ 100 ] = { 3 } ;
2019-03-19 03:23:45 +08:00
memcpy ( i18 . s1 , input , 100 ) ; // expected-warning {{'memcpy' will always overflow; destination buffer has size 24, but size argument is 100}}
2015-09-25 00:52:56 +08:00
clang_analyzer_eval ( i18 . s1 [ 0 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' i18 . s2 ' } }
clang_analyzer_eval ( i18 . s1 [ 1 ] = = 2 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i18 . s1 [ 2 ] = = 3 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i18 . s1 [ 3 ] = = 4 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i18 . i = = 10 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i18 . j = = 11 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
2022-02-13 21:02:46 +08:00
int f181 ( void ) {
2015-09-25 00:52:56 +08:00
struct ii i181 = { { 1 , 2 , 3 , 4 } , 5 , 6 } ;
i181 . i = 10 ;
i181 . j = 11 ;
i181 . s2 = strdup ( " hello " ) ;
char input [ 100 ] = { 3 } ;
memcpy ( i181 . s1 , input , 5 ) ; // invalidate the whole region of i181
clang_analyzer_eval ( i181 . s1 [ 0 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' i181 . s2 ' } }
clang_analyzer_eval ( i181 . s1 [ 1 ] = = 2 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i181 . s1 [ 2 ] = = 3 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i181 . s1 [ 3 ] = = 4 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i181 . i = = 10 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( i181 . j = = 11 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
// Test array with a symbolic offset.
struct jj {
char s1 [ 2 ] ;
char * s2 ;
} ;
struct JJ {
struct jj s1 [ 3 ] ;
char * s2 ;
} ;
int f19 ( int i ) {
struct JJ J0 = { { { 1 , 2 , 0 } , { 3 , 4 , 0 } , { 5 , 6 , 0 } } , 0 } ;
J0 . s2 = strdup ( " hello " ) ;
J0 . s1 [ 0 ] . s2 = strdup ( " hello " ) ;
J0 . s1 [ 1 ] . s2 = strdup ( " hi " ) ;
J0 . s1 [ 2 ] . s2 = strdup ( " world " ) ;
char input [ 2 ] = { ' a ' , ' b ' } ;
memcpy ( J0 . s1 [ i ] . s1 , input , 2 ) ;
clang_analyzer_eval ( J0 . s1 [ 0 ] . s1 [ 0 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by field ' s2 ' } } \
[Analyzer] Report every bug if only uniqueing location differs.
Summary:
Two CSA bug reports where only the uniqueing location is different
should be treated as different problems. The role of uniqueing location
is to differentiate bug reports.
Reviewers: Szelethus, baloghadamsoftware, NoQ, vsavchenko, xazax.hun, martong
Reviewed By: NoQ
Subscribers: NoQ, rnkovacs, xazax.hun, baloghadamsoftware, szepet, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, gamesh411, Charusso, martong, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83115
2020-07-15 17:05:22 +08:00
expected - warning { { Potential leak of memory pointed to by field ' s2 ' } } \
expected - warning { { Potential leak of memory pointed to by field ' s2 ' } } \
2015-09-25 00:52:56 +08:00
expected - warning { { Potential leak of memory pointed to by ' J0 . s2 ' } }
clang_analyzer_eval ( J0 . s1 [ 0 ] . s1 [ 1 ] = = 2 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( J0 . s1 [ 1 ] . s1 [ 0 ] = = 3 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( J0 . s1 [ 1 ] . s1 [ 1 ] = = 4 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( J0 . s1 [ 2 ] . s1 [ 0 ] = = 5 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( J0 . s1 [ 2 ] . s1 [ 1 ] = = 6 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( J0 . s1 [ i ] . s1 [ 0 ] = = 5 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( J0 . s1 [ i ] . s1 [ 1 ] = = 6 ) ; // expected-warning{{UNKNOWN}}
// FIXME: memory leak warning for J0.s2 should be emitted here instead of after memcpy call.
return 0 ; // no warning
}
// Test array with its super region having symbolic offseted regions.
int f20 ( int i ) {
struct aa * a20 = malloc ( sizeof ( struct aa ) * 2 ) ;
a20 [ 0 ] . s1 [ 0 ] = 1 ;
a20 [ 0 ] . s1 [ 1 ] = 2 ;
a20 [ 0 ] . s1 [ 2 ] = 3 ;
a20 [ 0 ] . s1 [ 3 ] = 4 ;
a20 [ 0 ] . s2 = strdup ( " hello " ) ;
a20 [ 1 ] . s1 [ 0 ] = 5 ;
a20 [ 1 ] . s1 [ 1 ] = 6 ;
a20 [ 1 ] . s1 [ 2 ] = 7 ;
a20 [ 1 ] . s1 [ 3 ] = 8 ;
a20 [ 1 ] . s2 = strdup ( " world " ) ;
a20 [ i ] . s2 = strdup ( " hola " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a20 [ 0 ] . s1 , input , 4 ) ;
clang_analyzer_eval ( a20 [ 0 ] . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 0 ] . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 0 ] . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 0 ] . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 0 ] . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 1 ] . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 1 ] . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 1 ] . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 1 ] . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ 1 ] . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ i ] . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ i ] . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ i ] . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ i ] . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a20 [ i ] . s2 = = 0 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' a20 ' } }
return 0 ;
}
// Test array's region and super region both having symbolic offsets.
int f21 ( int i ) {
struct aa * a21 = malloc ( sizeof ( struct aa ) * 2 ) ;
a21 [ 0 ] . s1 [ 0 ] = 1 ;
a21 [ 0 ] . s1 [ 1 ] = 2 ;
a21 [ 0 ] . s1 [ 2 ] = 3 ;
a21 [ 0 ] . s1 [ 3 ] = 4 ;
a21 [ 0 ] . s2 = 0 ;
a21 [ 1 ] . s1 [ 0 ] = 5 ;
a21 [ 1 ] . s1 [ 1 ] = 6 ;
a21 [ 1 ] . s1 [ 2 ] = 7 ;
a21 [ 1 ] . s1 [ 3 ] = 8 ;
a21 [ 1 ] . s2 = 0 ;
a21 [ i ] . s2 = strdup ( " hello " ) ;
a21 [ i ] . s1 [ 0 ] = 1 ;
a21 [ i ] . s1 [ 1 ] = 2 ;
a21 [ i ] . s1 [ 2 ] = 3 ;
a21 [ i ] . s1 [ 3 ] = 4 ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a21 [ i ] . s1 , input , 4 ) ;
clang_analyzer_eval ( a21 [ 0 ] . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 0 ] . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 0 ] . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 0 ] . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 0 ] . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 1 ] . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 1 ] . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 1 ] . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 1 ] . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ 1 ] . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ i ] . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ i ] . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ i ] . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ i ] . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a21 [ i ] . s2 = = 0 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' a21 ' } }
return 0 ;
}
// Test regions aliasing other regions.
struct ll {
char s1 [ 4 ] ;
char * s2 ;
} ;
struct mm {
char s3 [ 4 ] ;
char * s4 ;
} ;
2022-02-13 21:02:46 +08:00
int f24 ( void ) {
2015-09-25 00:52:56 +08:00
struct ll l24 = { { 1 , 2 , 3 , 4 } , 0 } ;
struct mm * m24 = ( struct mm * ) & l24 ;
m24 - > s4 = strdup ( " hello " ) ;
char input [ ] = { 1 , 2 , 3 , 4 } ;
memcpy ( m24 - > s3 , input , 4 ) ;
clang_analyzer_eval ( m24 - > s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m24 - > s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m24 - > s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m24 - > s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l24 . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l24 . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l24 . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l24 . s1 [ 3 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by field ' s4 ' } }
return 0 ;
}
// Test region with potential aliasing and symbolic offsets.
// Store assumes no aliasing.
int f25 ( int i , int j , struct ll * l , struct mm * m ) {
m - > s4 = strdup ( " hola " ) ; // m->s4 not tracked
m - > s3 [ 0 ] = 1 ;
m - > s3 [ 1 ] = 2 ;
m - > s3 [ 2 ] = 3 ;
m - > s3 [ 3 ] = 4 ;
m - > s3 [ j ] = 5 ; // invalidates m->s3
l - > s2 = strdup ( " hello " ) ; // l->s2 not tracked
l - > s1 [ 0 ] = 6 ;
l - > s1 [ 1 ] = 7 ;
l - > s1 [ 2 ] = 8 ;
l - > s1 [ 3 ] = 9 ;
l - > s1 [ i ] = 10 ; // invalidates l->s1
char input [ ] = { 1 , 2 , 3 , 4 } ;
memcpy ( m - > s3 , input , 4 ) ; // does not invalidate l->s1[i]
clang_analyzer_eval ( m - > s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m - > s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m - > s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m - > s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m - > s3 [ i ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m - > s3 [ j ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l - > s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l - > s1 [ i ] = = 1 ) ; // expected-warning{{FALSE}}
clang_analyzer_eval ( l - > s1 [ j ] = = 1 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
// Test size with symbolic size argument.
int f26 ( int i ) {
struct aa a26 = { { 1 , 2 , 3 , 4 } , 0 } ;
a26 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a26 . s1 , input , i ) ; // i assumed in bound
clang_analyzer_eval ( a26 . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a26 . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a26 . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a26 . s1 [ 3 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' a26 . s2 ' } }
return 0 ;
}
// Test sizeof as a size argument.
2022-02-13 21:02:46 +08:00
int f261 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a261 = { { 1 , 2 , 3 , 4 } , 0 } ;
a261 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( a261 . s1 , input , sizeof ( a261 . s1 ) ) ;
clang_analyzer_eval ( a261 . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a261 . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a261 . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a261 . s1 [ 3 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' a261 . s2 ' } }
return 0 ;
}
// Test negative size argument.
2022-02-13 21:02:46 +08:00
int f262 ( void ) {
2015-09-25 00:52:56 +08:00
struct aa a262 = { { 1 , 2 , 3 , 4 } , 0 } ;
a262 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
2019-03-19 03:23:45 +08:00
memcpy ( a262 . s1 , input , - 1 ) ; // expected-warning{{'memcpy' will always overflow; destination buffer has size 16, but size argument is 18446744073709551615}}
2015-09-25 00:52:56 +08:00
clang_analyzer_eval ( a262 . s1 [ 0 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' a262 . s2 ' } }
clang_analyzer_eval ( a262 . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a262 . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a262 . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
// Test size argument being an unknown value.
struct xx {
char s1 [ 4 ] ;
char * s2 ;
} ;
int f263 ( int n , char * len ) {
struct xx x263 = { 0 } ;
x263 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( x263 . s1 , input , * ( len + n ) ) ;
clang_analyzer_eval ( x263 . s1 [ 0 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( x263 . s1 [ 1 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( x263 . s1 [ 2 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( x263 . s1 [ 3 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( x263 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'x263.s2'}}
}
// Test casting regions with symbolic offseted sub regions.
int f27 ( int i ) {
struct mm m27 = { { 1 , 2 , 3 , 4 } , 0 } ;
m27 . s4 = strdup ( " hello " ) ;
m27 . s3 [ i ] = 5 ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( ( ( struct ll * ) ( & m27 ) ) - > s1 , input , 4 ) ;
clang_analyzer_eval ( m27 . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m27 . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m27 . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m27 . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m27 . s3 [ i ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' m27 . s4 ' } }
return 0 ;
}
int f28 ( int i , int j , int k , int l ) {
struct mm m28 [ 2 ] ;
m28 [ i ] . s4 = strdup ( " hello " ) ;
m28 [ j ] . s3 [ k ] = 1 ;
struct ll * l28 = ( struct ll * ) ( & m28 [ 1 ] ) ;
l28 - > s1 [ l ] = 2 ;
2018-11-30 11:27:50 +08:00
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ; // expected-warning{{Potential leak of memory pointed to by field 's4'}}
2015-09-25 00:52:56 +08:00
memcpy ( l28 - > s1 , input , 4 ) ;
clang_analyzer_eval ( m28 [ 0 ] . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 0 ] . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 0 ] . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 0 ] . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 1 ] . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 1 ] . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 1 ] . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ 1 ] . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ i ] . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ i ] . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ i ] . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ i ] . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m28 [ j ] . s3 [ k ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( l28 - > s1 [ l ] = = 2 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
int f29 ( int i , int j , int k , int l , int m ) {
struct mm m29 [ 2 ] ;
m29 [ i ] . s4 = strdup ( " hello " ) ;
m29 [ j ] . s3 [ k ] = 1 ;
struct ll * l29 = ( struct ll * ) ( & m29 [ l ] ) ;
l29 - > s1 [ m ] = 2 ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( l29 - > s1 , input , 4 ) ;
clang_analyzer_eval ( m29 [ 0 ] . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 0 ] . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 0 ] . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 0 ] . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 1 ] . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 1 ] . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 1 ] . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ 1 ] . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ i ] . s3 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ i ] . s3 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ i ] . s3 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( m29 [ i ] . s3 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
2018-04-20 07:24:32 +08:00
clang_analyzer_eval ( m29 [ j ] . s3 [ k ] = = 1 ) ; // expected-warning{{TRUE}}
2015-09-25 00:52:56 +08:00
clang_analyzer_eval ( l29 - > s1 [ m ] = = 2 ) ; // expected-warning{{UNKNOWN}}
2018-04-20 07:24:32 +08:00
// FIXME: Should warn that m29[i].s4 leaks. But not on the previous line,
// because l29 and m29 alias.
2015-09-25 00:52:56 +08:00
return 0 ;
}
// Test unions' fields.
union uu {
char x ;
char s1 [ 4 ] ;
} ;
2022-02-13 21:02:46 +08:00
int f30 ( void ) {
2015-09-25 00:52:56 +08:00
union uu u30 = { . s1 = { 1 , 2 , 3 , 4 } } ;
char input [ ] = { 1 , 2 , 3 , 4 } ;
memcpy ( u30 . s1 , input , 4 ) ;
clang_analyzer_eval ( u30 . s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( u30 . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( u30 . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( u30 . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( u30 . x = = 1 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
struct kk {
union uu u ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f31 ( void ) {
2015-09-25 00:52:56 +08:00
struct kk k31 ;
k31 . s2 = strdup ( " hello " ) ;
k31 . u . x = 1 ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( k31 . u . s1 , input , 4 ) ;
clang_analyzer_eval ( k31 . u . s1 [ 0 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' k31 . s2 ' } }
clang_analyzer_eval ( k31 . u . s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( k31 . u . s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( k31 . u . s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( k31 . u . x = = 1 ) ; // expected-warning{{UNKNOWN}}
// FIXME: memory leak warning for k31.s2 should be emitted here.
return 0 ;
}
union vv {
int x ;
char * s2 ;
} ;
2022-02-13 21:02:46 +08:00
int f32 ( void ) {
2015-09-25 00:52:56 +08:00
union vv v32 ;
v32 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( v32 . s2 , input , 4 ) ;
clang_analyzer_eval ( v32 . s2 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( v32 . s2 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( v32 . s2 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( v32 . s2 [ 3 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { Potential leak of memory pointed to by ' v32 . s2 ' } }
return 0 ;
}
struct nn {
int s1 ;
int i ;
int j ;
int k ;
char * s2 ;
} ;
// Test bad types to dest buffer.
2022-02-13 21:02:46 +08:00
int f33 ( void ) {
2015-09-25 00:52:56 +08:00
struct nn n33 = { 1 , 2 , 3 , 4 , 0 } ;
n33 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( n33 . s1 , input , 4 ) ; // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'}}
clang_analyzer_eval ( n33 . i = = 2 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( n33 . j = = 3 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( n33 . k = = 4 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( ( ( char * ) ( n33 . s1 ) ) [ 0 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { cast to ' char * ' from smaller integer type ' int ' } }
clang_analyzer_eval ( ( ( char * ) ( n33 . s1 ) ) [ 1 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { cast to ' char * ' from smaller integer type ' int ' } }
clang_analyzer_eval ( ( ( char * ) ( n33 . s1 ) ) [ 2 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { cast to ' char * ' from smaller integer type ' int ' } }
clang_analyzer_eval ( ( ( char * ) ( n33 . s1 ) ) [ 3 ] = = 1 ) ; / / expected - warning { { UNKNOWN } } \
expected - warning { { cast to ' char * ' from smaller integer type ' int ' } }
clang_analyzer_eval ( n33 . s2 = = 0 ) ; //expected-warning{{UNKNOWN}}
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'n33.s2'}}
}
// Test destination buffer being an unknown value.
struct ww {
int s1 [ 4 ] ;
char s2 ;
} ;
int f34 ( struct ww * w34 , int n ) {
w34 - > s2 = 3 ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( w34 - > s1 + n , input , 4 ) ;
clang_analyzer_eval ( w34 - > s1 [ 0 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( w34 - > s1 [ 1 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( w34 - > s1 [ 2 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( w34 - > s1 [ 3 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( w34 - > s1 [ n ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( w34 - > s2 = = 3 ) ; // expected-warning{{TRUE}}
return 0 ;
}
// Test dest buffer as an element region with a symbolic index and size parameter as a symbolic value.
struct yy {
char s1 [ 4 ] ;
char * s2 ;
} ;
int f35 ( int i , int n ) {
struct yy y35 = { { 1 , 2 , 3 , 4 } , 0 } ;
y35 . s2 = strdup ( " hello " ) ;
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
memcpy ( & ( y35 . s1 [ i ] ) , input , n ) ;
clang_analyzer_eval ( y35 . s1 [ 0 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( y35 . s1 [ 1 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( y35 . s1 [ 2 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( y35 . s1 [ 3 ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( y35 . s1 [ i ] = = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( y35 . s2 = = 0 ) ; // expected-warning{{UNKNOWN}}
return 0 ; // expected-warning{{Potential leak of memory pointed to by 'y35.s2'}}
}
// Test regions with negative offsets.
struct zz {
char s1 [ 4 ] ;
int s2 ;
} ;
int f36 ( struct zz * z36 ) {
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
z36 - > s1 [ 0 ] = 0 ;
z36 - > s1 [ 1 ] = 1 ;
z36 - > s1 [ 2 ] = 2 ;
z36 - > s1 [ 3 ] = 3 ;
z36 - > s2 = 10 ;
z36 = z36 - 1 ; // Decrement by 8 bytes (struct zz is 8 bytes).
z36 - > s1 [ 0 ] = 4 ;
z36 - > s1 [ 1 ] = 5 ;
z36 - > s1 [ 2 ] = 6 ;
z36 - > s1 [ 3 ] = 7 ;
z36 - > s2 = 11 ;
memcpy ( z36 - > s1 , input , 4 ) ;
clang_analyzer_eval ( z36 - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z36 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z36 - > s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z36 - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z36 - > s2 = = 11 ) ; // expected-warning{{TRUE}}
z36 = z36 + 1 ; // Increment back.
clang_analyzer_eval ( z36 - > s1 [ 0 ] = = 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( z36 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( z36 - > s1 [ 2 ] = = 2 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( z36 - > s1 [ 3 ] = = 3 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( z36 - > s2 = = 10 ) ; // expected-warning{{TRUE}}
return 0 ;
}
int f37 ( struct zz * z37 ) {
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
z37 - > s1 [ 0 ] = 0 ;
z37 - > s1 [ 1 ] = 1 ;
z37 - > s1 [ 2 ] = 2 ;
z37 - > s1 [ 3 ] = 3 ;
z37 - > s2 = 10 ;
z37 = ( struct zz * ) ( ( char * ) ( z37 ) - 4 ) ; // Decrement by 4 bytes (struct zz is 8 bytes).
z37 - > s1 [ 0 ] = 4 ;
z37 - > s1 [ 1 ] = 5 ;
z37 - > s1 [ 2 ] = 6 ;
z37 - > s1 [ 3 ] = 7 ;
z37 - > s2 = 11 ;
memcpy ( z37 - > s1 , input , 4 ) ;
clang_analyzer_eval ( z37 - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s2 = = 11 ) ; // expected-warning{{TRUE}}
z37 = ( struct zz * ) ( ( char * ) ( z37 ) + 4 ) ; // Increment back.
clang_analyzer_eval ( z37 - > s1 [ 0 ] = = 11 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( z37 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z37 - > s2 = = 10 ) ; // expected-warning{{TRUE}}
return 0 ;
}
int f38 ( struct zz * z38 ) {
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
z38 - > s1 [ 0 ] = 0 ;
z38 - > s1 [ 1 ] = 1 ;
z38 - > s1 [ 2 ] = 2 ;
z38 - > s1 [ 3 ] = 3 ;
z38 - > s2 = 10 ;
z38 = ( struct zz * ) ( ( char * ) ( z38 ) - 2 ) ; // Decrement by 2 bytes (struct zz is 8 bytes).
z38 - > s1 [ 0 ] = 4 ;
z38 - > s1 [ 1 ] = 5 ;
z38 - > s1 [ 2 ] = 6 ;
z38 - > s1 [ 3 ] = 7 ;
z38 - > s2 = 11 ;
memcpy ( z38 - > s1 , input , 4 ) ;
clang_analyzer_eval ( z38 - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s2 = = 11 ) ; // expected-warning{{TRUE}}
z38 = ( struct zz * ) ( ( char * ) ( z38 ) + 2 ) ; // Increment back.
clang_analyzer_eval ( z38 - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s1 [ 2 ] = = 11 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( z38 - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( z38 - > s2 = = 10 ) ; // expected-warning{{UNKNOWN}}
return 0 ;
}
// Test negative offsets with a different structure layout.
struct z0 {
int s2 ;
char s1 [ 4 ] ;
} ;
int f39 ( struct z0 * d39 ) {
char input [ ] = { ' a ' , ' b ' , ' c ' , ' d ' } ;
d39 - > s1 [ 0 ] = 0 ;
d39 - > s1 [ 1 ] = 1 ;
d39 - > s1 [ 2 ] = 2 ;
d39 - > s1 [ 3 ] = 3 ;
d39 - > s2 = 10 ;
d39 = ( struct z0 * ) ( ( char * ) ( d39 ) - 2 ) ; // Decrement by 2 bytes (struct z0 is 8 bytes).
d39 - > s1 [ 0 ] = 4 ;
d39 - > s1 [ 1 ] = 5 ;
d39 - > s1 [ 2 ] = 6 ;
d39 - > s1 [ 3 ] = 7 ;
d39 - > s2 = 11 ;
memcpy ( d39 - > s1 , input , 4 ) ;
clang_analyzer_eval ( d39 - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d39 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d39 - > s1 [ 2 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d39 - > s1 [ 3 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d39 - > s2 = = 11 ) ; // expected-warning{{TRUE}}
d39 = ( struct z0 * ) ( ( char * ) ( d39 ) + 2 ) ; // Increment back.
clang_analyzer_eval ( d39 - > s1 [ 0 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d39 - > s1 [ 1 ] = = 1 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( d39 - > s1 [ 2 ] = = 2 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( d39 - > s1 [ 3 ] = = 3 ) ; // expected-warning{{TRUE}}
// FIXME: d39->s2 should evaluate to at least UNKNOWN or FALSE,
// 'collectSubRegionBindings(...)' in RegionStore.cpp will need to
// handle a regions' upper boundary overflowing.
clang_analyzer_eval ( d39 - > s2 = = 10 ) ; // expected-warning{{TRUE}}
return 0 ;
}