junaire created this revision. junaire added reviewers: aaron.ballman, rsmith, erichkeane, dblaikie, rjmccall. Herald added a project: All. junaire requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Because lambda will create its own scope, so we shouldn't consider variables defined with the same name as redefinition error, if the new one is in a lambda. After this patch, clang is supposed to accept code below: void foo() { for (int x = [] { int x = 0; return x; }(); ;) ; } Fixes https://github.com/llvm/llvm-project/issues/54913 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D123840 Files: clang/lib/Sema/IdentifierResolver.cpp clang/test/SemaCXX/cxx1z-init-statement.cpp Index: clang/test/SemaCXX/cxx1z-init-statement.cpp =================================================================== --- clang/test/SemaCXX/cxx1z-init-statement.cpp +++ clang/test/SemaCXX/cxx1z-init-statement.cpp @@ -90,3 +90,18 @@ static_assert(constexpr_switch_init(-2) == 0, ""); static_assert(constexpr_switch_init(-5) == -1, ""); } + +int test_lambda_init() { + if (int x = []() {int x = 42; return x; }(); x) { + }; + + switch (int y = []() {int y = 42; return y; }(); y) { + case 42: + return 1; + } + + for (int x = [] { int x = 0; return x; }();;) + ; + + return 0; +} Index: clang/lib/Sema/IdentifierResolver.cpp =================================================================== --- clang/lib/Sema/IdentifierResolver.cpp +++ clang/lib/Sema/IdentifierResolver.cpp @@ -121,7 +121,10 @@ // of the controlled statement. // assert(S->getParent() && "No TUScope?"); - if (S->getParent()->getFlags() & Scope::ControlScope) { + // If the current decl is in a lambda, we shouldn't consider this is a + // redefinition as lambda has its own scope. + if (S->getParent()->getFlags() & Scope::ControlScope && + !S->isFunctionScope()) { S = S->getParent(); if (S->isDeclScope(D)) return true;
Index: clang/test/SemaCXX/cxx1z-init-statement.cpp =================================================================== --- clang/test/SemaCXX/cxx1z-init-statement.cpp +++ clang/test/SemaCXX/cxx1z-init-statement.cpp @@ -90,3 +90,18 @@ static_assert(constexpr_switch_init(-2) == 0, ""); static_assert(constexpr_switch_init(-5) == -1, ""); } + +int test_lambda_init() { + if (int x = []() {int x = 42; return x; }(); x) { + }; + + switch (int y = []() {int y = 42; return y; }(); y) { + case 42: + return 1; + } + + for (int x = [] { int x = 0; return x; }();;) + ; + + return 0; +} Index: clang/lib/Sema/IdentifierResolver.cpp =================================================================== --- clang/lib/Sema/IdentifierResolver.cpp +++ clang/lib/Sema/IdentifierResolver.cpp @@ -121,7 +121,10 @@ // of the controlled statement. // assert(S->getParent() && "No TUScope?"); - if (S->getParent()->getFlags() & Scope::ControlScope) { + // If the current decl is in a lambda, we shouldn't consider this is a + // redefinition as lambda has its own scope. + if (S->getParent()->getFlags() & Scope::ControlScope && + !S->isFunctionScope()) { S = S->getParent(); if (S->isDeclScope(D)) return true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits