From 2a80d3ae14f6f823e28637fd28b5808a6e4aa5ba Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 21 Mar 2018 13:09:09 +0000 Subject: [PATCH] C++: show private field accessor hints for const accesses (PR c++/84892) gcc/cp/ChangeLog: PR c++/84892 * search.c (field_accessor_p): Use class_of_this_parm rather than type_of_this_parm, to check that "this" is a "const T *", rather than a "T *const". gcc/testsuite/ChangeLog: PR c++/84892 * g++.dg/other/accessor-fixits-1.C (test_access_const_t1_color): New. (test_deref_const_t1_color): New. * g++.dg/other/accessor-fixits-5.C: New testcase. From-SVN: r258716 --- gcc/cp/ChangeLog | 7 +++ gcc/cp/search.c | 4 +- gcc/testsuite/ChangeLog | 8 ++++ .../g++.dg/other/accessor-fixits-1.C | 44 +++++++++++++++++++ .../g++.dg/other/accessor-fixits-5.C | 33 ++++++++++++++ 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/accessor-fixits-5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index da19013d21c..74bc9867c1d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-03-21 David Malcolm + + PR c++/84892 + * search.c (field_accessor_p): Use class_of_this_parm rather than + type_of_this_parm, to check that "this" is a "const T *", rather + than a "T *const". + 2018-03-21 Nathan Sidwell * class.c (finish_struct_anon_r): Refactor, deprecate anything diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 796209f0e72..ddcff69ae6f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1747,8 +1747,8 @@ field_accessor_p (tree fn, tree field_decl, bool const_p) that the "this" parameter is const. */ if (const_p) { - tree this_type = type_of_this_parm (fntype); - if (!TYPE_READONLY (this_type)) + tree this_class = class_of_this_parm (fntype); + if (!TYPE_READONLY (this_class)) return false; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 64c8d977b11..5d62630a9fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-03-21 David Malcolm + + PR c++/84892 + * g++.dg/other/accessor-fixits-1.C + (test_access_const_t1_color): New. + (test_deref_const_t1_color): New. + * g++.dg/other/accessor-fixits-5.C: New testcase. + 2018-03-21 Tom de Vries PR tree-optimization/83126 diff --git a/gcc/testsuite/g++.dg/other/accessor-fixits-1.C b/gcc/testsuite/g++.dg/other/accessor-fixits-1.C index cc96b877671..fd46a522486 100644 --- a/gcc/testsuite/g++.dg/other/accessor-fixits-1.C +++ b/gcc/testsuite/g++.dg/other/accessor-fixits-1.C @@ -35,6 +35,28 @@ int test_access_t1_color (t1 &ref) { dg-end-multiline-output "" } */ } +int test_access_const_t1_color (const t1 &ref) +{ + return ref.m_color; // { dg-error ".int t1::m_color. is private within this context" } + /* { dg-begin-multiline-output "" } + return ref.m_color; + ^~~~~~~ + { dg-end-multiline-output "" } */ + + + /* { dg-begin-multiline-output "" } + int m_color; + ^~~~~~~ + { dg-end-multiline-output "" } */ + + // { dg-message "field .int t1::m_color. can be accessed via .int t1::get_color\\(\\) const." "" { target *-*-* } .-12 } + /* { dg-begin-multiline-output "" } + return ref.m_color; + ^~~~~~~ + get_color() + { dg-end-multiline-output "" } */ +} + int test_access_t1_shape (t1 &ref) { return ref.m_shape; // { dg-error ".int t1::m_shape. is protected within this context" } @@ -79,6 +101,28 @@ int test_deref_t1_color (t1 *ptr) { dg-end-multiline-output "" } */ } +int test_deref_const_t1_color (const t1 *ptr) +{ + return ptr->m_color; // { dg-error ".int t1::m_color. is private within this context" } + /* { dg-begin-multiline-output "" } + return ptr->m_color; + ^~~~~~~ + { dg-end-multiline-output "" } */ + + + /* { dg-begin-multiline-output "" } + int m_color; + ^~~~~~~ + { dg-end-multiline-output "" } */ + + // { dg-message "field .int t1::m_color. can be accessed via .int t1::get_color\\(\\) const." "" { target *-*-* } .-12 } + /* { dg-begin-multiline-output "" } + return ptr->m_color; + ^~~~~~~ + get_color() + { dg-end-multiline-output "" } */ +} + int test_deref_t1_shape (t1 *ptr) { return ptr->m_shape; // { dg-error ".int t1::m_shape. is protected within this context" } diff --git a/gcc/testsuite/g++.dg/other/accessor-fixits-5.C b/gcc/testsuite/g++.dg/other/accessor-fixits-5.C new file mode 100644 index 00000000000..cf72d784330 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/accessor-fixits-5.C @@ -0,0 +1,33 @@ +// PR c++/84892 +// { dg-options "-fdiagnostics-show-caret" } + +class S { +private: + bool field; + +public: + bool get_field() const { + return field; + } +}; + +bool thingy(const S & s) { + return s.field; // { dg-error "'bool S::field' is private within this context" } + /* { dg-begin-multiline-output "" } + return s.field; + ^~~~~ + { dg-end-multiline-output "" } */ + + // { dg-message "declared private here" "" { target *-*-* } 6 } + /* { dg-begin-multiline-output "" } + bool field; + ^~~~~ + { dg-end-multiline-output "" } */ + + // { dg-message "field 'bool S::field' can be accessed via 'bool S::get_field\\(\\) const'" "" { target *-*-* } .-12 } + /* { dg-begin-multiline-output "" } + return s.field; + ^~~~~ + get_field() + { dg-end-multiline-output "" } */ +} -- 2.30.2