[Clang][Sema] Fix invalid redefinition error in if/switch/for statement
Clang should no longer incorrectly diagnose a variable declaration inside of a lambda expression that shares the name of a variable in a containing if/while/for/switch init statement as a redeclaration. 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 Differential Revision: https://reviews.llvm.org/D123840
This commit is contained in:
parent
61bd985f2a
commit
be0905a333
|
@ -119,6 +119,10 @@ Bug Fixes
|
||||||
This fixes Issue `Issue 52802 <https://github.com/llvm/llvm-project/issues/52802>`_.
|
This fixes Issue `Issue 52802 <https://github.com/llvm/llvm-project/issues/52802>`_.
|
||||||
- Unknown type attributes with a ``[[]]`` spelling are no longer diagnosed twice.
|
- Unknown type attributes with a ``[[]]`` spelling are no longer diagnosed twice.
|
||||||
This fixes Issue `Issue 54817 <https://github.com/llvm/llvm-project/issues/54817>`_.
|
This fixes Issue `Issue 54817 <https://github.com/llvm/llvm-project/issues/54817>`_.
|
||||||
|
- Clang should no longer incorrectly diagnose a variable declaration inside of
|
||||||
|
a lambda expression that shares the name of a variable in a containing
|
||||||
|
if/while/for/switch init statement as a redeclaration.
|
||||||
|
This fixes `Issue 54913 <https://github.com/llvm/llvm-project/issues/54913>`_.
|
||||||
|
|
||||||
Improvements to Clang's diagnostics
|
Improvements to Clang's diagnostics
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -121,7 +121,10 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
|
||||||
// of the controlled statement.
|
// of the controlled statement.
|
||||||
//
|
//
|
||||||
assert(S->getParent() && "No TUScope?");
|
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();
|
S = S->getParent();
|
||||||
if (S->isDeclScope(D))
|
if (S->isDeclScope(D))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -90,3 +90,18 @@ void test_constexpr_init_stmt() {
|
||||||
static_assert(constexpr_switch_init(-2) == 0, "");
|
static_assert(constexpr_switch_init(-2) == 0, "");
|
||||||
static_assert(constexpr_switch_init(-5) == -1, "");
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue