diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9b8be084452e7fd1162995e26b44f239a5abd087..bd43f885ebe32730a0d2f0ec8a8bfb6b8a31c302 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -14570,9 +14570,19 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, decomp = &decomp_d; decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1; decomp->decl = d; + bool seen_name_independent_decl = false; for (unsigned int i = 0; i < decomp->count; i++, d = DECL_CHAIN (d)) { + if (name_independent_decl_p (d)) + { + /* If there is more than one _ decl in + the structured binding, just push and move it + away once. */ + if (seen_name_independent_decl) + continue; + seen_name_independent_decl = true; + } tree name = DECL_NAME (d); names.safe_push (name); bindings.safe_push (IDENTIFIER_BINDING (name)); diff --git a/gcc/testsuite/g++.dg/cpp26/name-independent-decl10.C b/gcc/testsuite/g++.dg/cpp26/name-independent-decl10.C new file mode 100644 index 0000000000000000000000000000000000000000..792c2bd0c6b34d1f553157b0b24aeddfa46b982c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/name-independent-decl10.C @@ -0,0 +1,63 @@ +// PR c++/115586 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct S { int a, b, c; }; + +void +foo () +{ + S s[4] = {}; + for (auto [_, _, a] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++_; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "reference to '_' is ambiguous" "" { target *-*-* } .-1 } + for (auto _ : s) + ++_.b; + for (auto [a, _, b] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + ++_; + for (auto [_, _, a] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + ++_; // { dg-error "reference to '_' is ambiguous" } + } + for (auto _ : s) + { + ++_.b; + int _ = 2; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++_; // { dg-error "reference to '_' is ambiguous" } + } + for (auto [a, _, b] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + { + ++_; + int _ = ++b; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++_; // { dg-error "reference to '_' is ambiguous" } + } +} + +void +bar () +{ + S s[4] = {}; + auto [_, c, _] = s[0]; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++_; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "reference to '_' is ambiguous" "" { target *-*-* } .-1 } + for (auto [a, _, _] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++_; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "reference to '_' is ambiguous" "" { target *-*-* } .-1 } + for (auto _ : s) + ++_.c; + for (auto [a, b, _] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + ++_; + for (auto [a, _, _] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + ++_; // { dg-error "reference to '_' is ambiguous" } + ++a; + } + for (auto _ : s) + int _ = 5; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + for (auto [a, b, _] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + { + ++_; + int _ = a + b; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++_; // { dg-error "reference to '_' is ambiguous" } + } +} diff --git a/gcc/testsuite/g++.dg/cpp26/name-independent-decl9.C b/gcc/testsuite/g++.dg/cpp26/name-independent-decl9.C new file mode 100644 index 0000000000000000000000000000000000000000..0a8ef0405970047eef34e82981cce8b8acfeeba2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/name-independent-decl9.C @@ -0,0 +1,49 @@ +// PR c++/115586 +// { dg-do compile { target c++11 } } +// { dg-options "-Wunused-variable -Wunused-but-set-variable -Wunused-parameter -Wshadow" } + +struct S { int a, b, c; }; + +void +foo () +{ + S s[4] = {}; + for (auto [_, _, a] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++a; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + for (auto _ : s) + ++_.b; + for (auto [a, _, b] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + ++a; + for (auto [_, _, a] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + int _ = ++a; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + for (auto _ : s) + { + int _ = 2; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + } + for (auto [a, _, b] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + int _ = ++b; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } +} + +void +bar () +{ + S s[4] = {}; + auto [_, c, _] = s[0]; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++c; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + for (auto [a, _, _] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + ++a; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + for (auto _ : s) + ++_.c; + for (auto [a, b, _] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + ++b; + for (auto [a, _, _] : s) // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + int _ = ++a; + } + for (auto _ : s) + int _ = 5; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + for (auto [a, b, _] : s) // { dg-warning "structured bindings only available with" "" { target c++14_down } } + { + int _ = a + b; // { dg-warning "name-independent declarations only available with" "" { target c++23_down } } + } +}