Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
      2 
      3 // FIXME: Only the stack-address checking in Sema catches this right now, and
      4 // the stack analyzer doesn't handle the ImplicitCastExpr (lvalue).
      5 const int& g() {
      6   int s;
      7   return s; // expected-warning{{Address of stack memory associated with local variable 's' returned}} expected-warning{{reference to stack memory associated with local variable 's' returned}}
      8 }
      9 
     10 const int& g2() {
     11   int s1;
     12   int &s2 = s1; // expected-note {{binding reference variable 's2' here}}
     13   return s2; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{reference to stack memory associated with local variable 's1' returned}}
     14 }
     15 
     16 const int& g3() {
     17   int s1;
     18   int &s2 = s1; // expected-note {{binding reference variable 's2' here}}
     19   int &s3 = s2; // expected-note {{binding reference variable 's3' here}}
     20   return s3; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{reference to stack memory associated with local variable 's1' returned}}
     21 }
     22 
     23 int get_value();
     24 
     25 const int &get_reference1() { return get_value(); } // expected-warning{{Address of stack memory associated with temporary object of type 'const int' returned}} expected-warning {{returning reference to local temporary}}
     26 
     27 const int &get_reference2() {
     28   const int &x = get_value(); // expected-note {{binding reference variable 'x' here}}
     29   return x; // expected-warning{{Address of stack memory associated with temporary object of type 'const int' returned}} expected-warning {{returning reference to local temporary}}
     30 }
     31 
     32 const int &get_reference3() {
     33   const int &x1 = get_value(); // expected-note {{binding reference variable 'x1' here}}
     34   const int &x2 = x1; // expected-note {{binding reference variable 'x2' here}}
     35   return x2; // expected-warning{{Address of stack memory associated with temporary object of type 'const int' returned}} expected-warning {{returning reference to local temporary}}
     36 }
     37 
     38 int global_var;
     39 int *f1() {
     40   int &y = global_var;
     41   return &y;
     42 }
     43 
     44 int *f2() {
     45   int x1;
     46   int &x2 = x1; // expected-note {{binding reference variable 'x2' here}}
     47   return &x2; // expected-warning{{Address of stack memory associated with local variable 'x1' returned}} expected-warning {{address of stack memory associated with local variable 'x1' returned}}
     48 }
     49 
     50 int *f3() {
     51   int x1;
     52   int *const &x2 = &x1; // expected-note {{binding reference variable 'x2' here}}
     53   return x2; // expected-warning {{address of stack memory associated with local variable 'x1' returned}} expected-warning {{Address of stack memory associated with local variable 'x1' returned to caller}}
     54 }
     55 
     56 const int *f4() {
     57   const int &x1 = get_value(); // expected-note {{binding reference variable 'x1' here}}
     58   const int &x2 = x1; // expected-note {{binding reference variable 'x2' here}}
     59   return &x2; // expected-warning{{Address of stack memory associated with temporary object of type 'const int' returned}} expected-warning {{returning address of local temporary}}
     60 }
     61 
     62 struct S {
     63   int x;
     64 };
     65 
     66 int *mf() {
     67   S s1;
     68   S &s2 = s1; // expected-note {{binding reference variable 's2' here}}
     69   int &x = s2.x; // expected-note {{binding reference variable 'x' here}}
     70   return &x; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{address of stack memory associated with local variable 's1' returned}}
     71 }
     72 
     73 void *lf() {
     74     label:
     75     void *const &x = &&label; // expected-note {{binding reference variable 'x' here}}
     76     return x; // expected-warning {{returning address of label, which is local}}
     77 }
     78 
     79 template <typename T>
     80 struct TS {
     81   int *get();
     82   int *m() {
     83     int *&x = get();
     84     return x;
     85   }
     86 };
     87