1 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -D AVOID %s 2 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s 3 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow-all %s 4 // RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wshadow-all %s 5 // RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -Wshadow-all %s 6 7 void foo(int param) { // expected-note 1+ {{previous declaration is here}} 8 int var = 0; // expected-note 1+ {{previous declaration is here}} 9 10 // Avoid warnings for variables that aren't implicitly captured. 11 { 12 #ifdef AVOID 13 auto f1 = [=] { int var = 1; }; // no warning 14 auto f2 = [&] { int var = 2; }; // no warning 15 auto f3 = [=] (int param) { ; }; // no warning 16 auto f4 = [&] (int param) { ; }; // no warning 17 auto f5 = [=] { static int var = 1; }; // no warning 18 auto f6 = [&] { static int var = 2; }; // no warning 19 #else 20 auto f1 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}} 21 auto f2 = [&] { int var = 2; }; // expected-warning {{declaration shadows a local variable}} 22 auto f3 = [=] (int param) { ; }; // expected-warning {{declaration shadows a local variable}} 23 auto f4 = [&] (int param) { ; }; // expected-warning {{declaration shadows a local variable}} 24 auto f5 = [=] { static int var = 1; }; // expected-warning {{declaration shadows a local variable}} 25 auto f6 = [&] { static int var = 2; }; // expected-warning {{declaration shadows a local variable}} 26 #endif 27 } 28 29 // Warn for variables that are implicitly captured. 30 { 31 auto f1 = [=] () { 32 { 33 int var = 1; // expected-warning {{declaration shadows a local variable}} 34 } 35 int x = var; // expected-note {{variable 'var' is captured here}} 36 }; 37 auto f2 = [&] 38 #ifdef AVOID 39 (int param) { 40 #else 41 (int param) { // expected-warning {{declaration shadows a local variable}} 42 #endif 43 int x = var; // expected-note {{variable 'var' is captured here}} 44 int var = param; // expected-warning {{declaration shadows a local variable}} 45 }; 46 } 47 48 // Warn for variables that are explicitly captured when a lambda has a default 49 // capture specifier. 50 { 51 auto f1 = [=, &var] () { // expected-note {{variable 'var' is captured here}} 52 int x = param; // expected-note {{variable 'param' is captured here}} 53 int var = 0; // expected-warning {{declaration shadows a local variable}} 54 int param = 0; // expected-warning {{declaration shadows a local variable}} 55 }; 56 } 57 58 // Warn normally inside of lambdas. 59 auto l1 = [] { // expected-note {{previous declaration is here}} 60 int x = 1; // expected-note {{previous declaration is here}} 61 { int x = 2; } // expected-warning {{declaration shadows a local variable}} 62 }; 63 auto l2 = [] (int x) { // expected-note {{previous declaration is here}} 64 { int x = 1; } // expected-warning {{declaration shadows a local variable}} 65 }; 66 67 // Avoid warnings for variables that aren't explicitly captured. 68 { 69 #ifdef AVOID 70 auto f1 = [] { int var = 1; }; // no warning 71 auto f2 = [] (int param) { ; }; // no warning 72 auto f3 = [param] () { int var = 1; }; // no warning 73 auto f4 = [var] (int param) { ; }; // no warning 74 auto f5 = [param] () { static int var = 1; }; // no warning 75 auto f6 = [] { static int var = 1; }; // no warning 76 #else 77 auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}} 78 auto f2 = [] (int param) { ; }; // expected-warning {{declaration shadows a local variable}} 79 auto f3 = [param] () { int var = 1; }; // expected-warning {{declaration shadows a local variable}} 80 auto f4 = [var] (int param) { ; }; // expected-warning {{declaration shadows a local variable}} 81 auto f5 = [param] () { static int var = 1; }; // expected-warning {{declaration shadows a local variable}} 82 auto f6 = [] { static int var = 1; }; // expected-warning {{declaration shadows a local variable}} 83 #endif 84 }; 85 86 // Warn for variables that are explicitly captured. 87 { 88 auto f1 = [var] () { // expected-note {{variable 'var' is explicitly captured here}} 89 int var = 1; // expected-warning {{declaration shadows a local variable}} 90 }; 91 auto f2 = [param] // expected-note {{variable 'param' is explicitly captured here}} 92 (int param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}} 93 } 94 95 // Warn for variables defined in the capture list. 96 auto l3 = [z = var] { // expected-note {{previous declaration is here}} 97 #ifdef AVOID 98 int var = 1; // no warning 99 #else 100 int var = 1; // expected-warning {{declaration shadows a local variable}} 101 #endif 102 { int z = 1; } // expected-warning {{declaration shadows a local variable}} 103 }; 104 #ifdef AVOID 105 auto l4 = [var = param] (int param) { ; }; // no warning 106 #else 107 auto l4 = [var = param](int param) { ; }; // expected-warning 2{{declaration shadows a local variable}} 108 #endif 109 110 // Make sure that inner lambdas work as well. 111 auto l5 = [var, l1] { // expected-note {{variable 'l1' is explicitly captured here}} 112 auto l1 = [] { // expected-warning {{declaration shadows a local variable}} 113 #ifdef AVOID 114 int var = 1; // no warning 115 #else 116 int var = 1; // expected-warning {{declaration shadows a local variable}} 117 #endif 118 }; 119 #ifdef AVOID 120 auto f1 = [] { int var = 1; }; // no warning 121 auto f2 = [=] { int var = 1; }; // no warning 122 #else 123 auto f1 = [] { int var = 1; }; // expected-warning {{declaration shadows a local variable}} 124 auto f2 = [=] { int var = 1; }; // expected-warning {{declaration shadows a local variable}} 125 #endif 126 auto f3 = [var] // expected-note {{variable 'var' is explicitly captured here}} 127 { int var = 1; }; // expected-warning {{declaration shadows a local variable}} 128 auto f4 = [&] { 129 int x = var; // expected-note {{variable 'var' is captured here}} 130 int var = 2; // expected-warning {{declaration shadows a local variable}} 131 }; 132 }; 133 auto l6 = [&] { 134 auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}} 135 int param = 0; // expected-warning {{declaration shadows a local variable}} 136 }; 137 }; 138 auto l7 = [&] { 139 auto f1 = [param] { // expected-note {{variable 'param' is explicitly captured here}} 140 static int param = 0; // expected-warning {{declaration shadows a local variable}} 141 }; 142 }; 143 144 // Generic lambda arguments should work. 145 #ifdef AVOID 146 auto g1 = [](auto param) { ; }; // no warning 147 auto g2 = [=](auto param) { ; }; // no warning 148 #else 149 auto g1 = [](auto param) { ; }; // expected-warning {{declaration shadows a local variable}} 150 auto g2 = [=](auto param) { ; }; // expected-warning {{declaration shadows a local variable}} 151 #endif 152 auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}} 153 (auto param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}} 154 } 155 156 void avoidWarningWhenRedefining() { 157 int a = 1; 158 auto l = [b = a] { // expected-note {{previous definition is here}} 159 // Don't warn on redefinitions. 160 int b = 0; // expected-error {{redefinition of 'b'}} 161 }; 162 } 163 164 namespace GH61105 { 165 void f() { 166 int y = 0; 167 int x = 0; 168 #if __cplusplus >= 202002L 169 auto l1 = [y]<typename y>(y) { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \ 170 // expected-note {{template parameter is declared here}} 171 auto l2 = [=]<typename y>() { int a = y; return 0; }; // expected-error {{'y' does not refer to a value}} \ 172 // expected-note {{declared here}} 173 auto l3 = [&, y]<typename y, typename>(y) { int a = x; return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \ 174 // expected-note {{template parameter is declared here}} 175 auto l4 = [x, y]<typename y, int x>() { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \ 176 // expected-error {{declaration of 'x' shadows template parameter}} \ 177 // expected-note 2{{template parameter is declared here}} 178 auto l5 = []<typename y>(y) { return 0; }; // No diagnostic 179 #endif 180 } 181 } 182