xref: /aosp_15_r20/external/clang/test/Analysis/stackaddrleak.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
2*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
3*67e74705SXin Li 
4*67e74705SXin Li typedef __INTPTR_TYPE__ intptr_t;
5*67e74705SXin Li char const *p;
6*67e74705SXin Li 
f0()7*67e74705SXin Li void f0() {
8*67e74705SXin Li   char const str[] = "This will change";
9*67e74705SXin Li   p = str;
10*67e74705SXin Li }  // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
11*67e74705SXin Li 
f1()12*67e74705SXin Li void f1() {
13*67e74705SXin Li   char const str[] = "This will change";
14*67e74705SXin Li   p = str;
15*67e74705SXin Li   p = 0; // no-warning
16*67e74705SXin Li }
17*67e74705SXin Li 
f2()18*67e74705SXin Li void f2() {
19*67e74705SXin Li   p = (const char *) __builtin_alloca(12);
20*67e74705SXin Li } // expected-warning{{Address of stack memory allocated by call to alloca() on line 19 is still referred to by the global variable 'p' upon returning to the caller.  This will be a dangling reference}}
21*67e74705SXin Li 
22*67e74705SXin Li // PR 7383 - previously the stack address checker would crash on this example
23*67e74705SXin Li //  because it would attempt to do a direct load from 'pr7383_list'.
pr7383(__const char * __)24*67e74705SXin Li static int pr7383(__const char *__)
25*67e74705SXin Li {
26*67e74705SXin Li   return 0;
27*67e74705SXin Li }
28*67e74705SXin Li extern __const char *__const pr7383_list[];
29*67e74705SXin Li 
30*67e74705SXin Li // Test that we catch multiple returns via globals when analyzing a function.
test_multi_return()31*67e74705SXin Li void test_multi_return() {
32*67e74705SXin Li   static int *a, *b;
33*67e74705SXin Li   int x;
34*67e74705SXin Li   a = &x;
35*67e74705SXin Li   b = &x;
36*67e74705SXin Li } // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the static variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the static variable 'b' upon returning}}
37*67e74705SXin Li 
returnAsNonLoc()38*67e74705SXin Li intptr_t returnAsNonLoc() {
39*67e74705SXin Li   int x;
40*67e74705SXin Li   return (intptr_t)&x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller}}
41*67e74705SXin Li }
42*67e74705SXin Li 
returnAsBool()43*67e74705SXin Li bool returnAsBool() {
44*67e74705SXin Li   int x;
45*67e74705SXin Li   return &x; // no-warning
46*67e74705SXin Li }
47*67e74705SXin Li 
assignAsNonLoc()48*67e74705SXin Li void assignAsNonLoc() {
49*67e74705SXin Li   extern intptr_t ip;
50*67e74705SXin Li   int x;
51*67e74705SXin Li   ip = (intptr_t)&x;
52*67e74705SXin Li } // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'ip' upon returning}}
53*67e74705SXin Li 
assignAsBool()54*67e74705SXin Li void assignAsBool() {
55*67e74705SXin Li   extern bool b;
56*67e74705SXin Li   int x;
57*67e74705SXin Li   b = &x;
58*67e74705SXin Li } // no-warning
59