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