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