From 9aee04a4c032b075d07bdde6f8bd22b06d709f42 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Thu, 5 Apr 2018 17:43:55 +0300 Subject: [PATCH] Implement P0969 gcc/cp Implement P0969 * decl.c (find_decomp_class_base): Check accessibility instead of declared access, adjust diagnostic. testsuite/ Implement P0969 * g++.dg/cpp1z/decomp4.C: Adjust. * g++.dg/cpp1z/decomp38.C: New. From-SVN: r259129 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/decl.c | 4 +-- gcc/testsuite/g++.dg/cpp1z/decomp38.C | 48 +++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/decomp4.C | 4 +-- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp38.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 09019061285..37d82bd8c4b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-04-05 Ville Voutilainen + + Implement P0969 + * decl.c (find_decomp_class_base): Check accessibility instead + of declared access, adjust diagnostic. + 2018-04-05 Ville Voutilainen Implement P0961 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 31d9c983e9f..b2e509e4d05 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7322,9 +7322,9 @@ find_decomp_class_base (location_t loc, tree type, tree ret) inform (DECL_SOURCE_LOCATION (field), "declared here"); return error_mark_node; } - else if (TREE_PRIVATE (field) || TREE_PROTECTED (field)) + else if (!accessible_p (type, field, true)) { - error_at (loc, "cannot decompose non-public member %qD of %qT", + error_at (loc, "cannot decompose inaccessible member %qD of %qT", field, type); inform (DECL_SOURCE_LOCATION (field), TREE_PRIVATE (field) diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp38.C b/gcc/testsuite/g++.dg/cpp1z/decomp38.C new file mode 100644 index 00000000000..fc69c02e4d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/decomp38.C @@ -0,0 +1,48 @@ +// { dg-additional-options -std=c++17 } +// { dg-do compile } + +class X +{ + int a, b; + void f() + { + auto[x,y] = *this; + } +}; + +class X2 +{ + int a, b; + void f(X2& other) + { + auto[x,y] = other; + } +}; + +struct X3 +{ + friend void foo(); +private: + int a; +}; + +void foo() +{ + X3 x; + auto [a] = x; +} + +struct X4 +{ + int a; +}; + +struct X5 : private X4 +{ + friend void foo2(); +}; + +void foo2() { + X5 x; + auto [a] = x; +} diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp4.C b/gcc/testsuite/g++.dg/cpp1z/decomp4.C index e50b882f189..69b5455df3b 100644 --- a/gcc/testsuite/g++.dg/cpp1z/decomp4.C +++ b/gcc/testsuite/g++.dg/cpp1z/decomp4.C @@ -18,10 +18,10 @@ test (A &a, B &b, C &c, D &d, E &e, F &f, G &g, H &h, I &i) // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } auto [ k ] { b }; // { dg-error "cannot decompose class type 'B' because it has an anonymous union member" } // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto [ l, l2 ] = c; // { dg-error "cannot decompose non-public member 'C::b' of 'C'" } + auto [ l, l2 ] = c; // { dg-error "cannot decompose inaccessible member 'C::b' of 'C'" } // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } auto [ m ] = d; // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } } - auto [ n ] { e }; // { dg-error "cannot decompose non-public member 'E::a' of 'E'" } + auto [ n ] { e }; // { dg-error "cannot decompose inaccessible member 'E::a' of 'E'" } // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } auto [ o ] { f }; // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } } auto & [ p ] { g }; // { dg-error "cannot decompose class type 'G': both it and its base class 'F' have non-static data members" } -- 2.30.2