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