diff options
author | Anthony Sharp <anthonysharp15@gmail.com> | 2021-01-22 22:36:06 +0000 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-01-23 17:48:31 -0500 |
commit | 7e0f147a29f42d6149585573650bd4827f3b2b93 (patch) | |
tree | a852452165cc39e93ebf00c3de49a1158aae09ae /gcc/cp/search.c | |
parent | c63f091db89a56ae56b2bfa2ba4d9e956bd9693f (diff) | |
download | gcc-7e0f147a29f42d6149585573650bd4827f3b2b93.zip gcc-7e0f147a29f42d6149585573650bd4827f3b2b93.tar.gz gcc-7e0f147a29f42d6149585573650bd4827f3b2b93.tar.bz2 |
c++: private inheritance access diagnostics fix [PR17314]
This patch fixes PR17314. Previously, when class C attempted
to access member a declared in class A through class B, where class B
privately inherits from A and class C inherits from B, GCC would correctly
report an access violation, but would erroneously report that the reason was
because a was "protected", when in fact, from the point of view of class C,
it was really "private". This patch updates the diagnostics code to generate
more correct errors in cases of failed inheritance such as these.
The reason this bug happened was because GCC was examining the
declared access of decl, instead of looking at it in the
context of class inheritance.
gcc/cp/ChangeLog:
2021-01-21 Anthony Sharp <anthonysharp15@gmail.com>
* call.c (complain_about_access): Altered function.
* cp-tree.h (complain_about_access): Changed parameters of function.
(get_parent_with_private_access): Declared new function.
* search.c (get_parent_with_private_access): Defined new function.
* semantics.c (enforce_access): Modified function.
* typeck.c (complain_about_unrecognized_member): Updated function
arguments in complain_about_access.
gcc/testsuite/ChangeLog:
2021-01-21 Anthony Sharp <anthonysharp15@gmail.com>
* g++.dg/lookup/scoped1.C: Modified testcase to run successfully
with changes.
* g++.dg/tc1/dr142.C: Same as above.
* g++.dg/tc1/dr52.C: Same as above.
* g++.old-deja/g++.brendan/visibility6.C: Same as above.
* g++.old-deja/g++.brendan/visibility8.C: Same as above.
* g++.old-deja/g++.jason/access8.C: Same as above.
* g++.old-deja/g++.law/access4.C: Same as above.
* g++.old-deja/g++.law/visibility12.C: Same as above.
* g++.old-deja/g++.law/visibility4.C: Same as above.
* g++.old-deja/g++.law/visibility8.C: Same as above.
* g++.old-deja/g++.other/access4.C: Same as above.
Diffstat (limited to 'gcc/cp/search.c')
-rw-r--r-- | gcc/cp/search.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 81bdd45..7b18368 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -122,6 +122,41 @@ dfs_lookup_base (tree binfo, void *data_) return NULL_TREE; } +/* This deals with bug PR17314. + + DECL is a declaration and BINFO represents a class that has attempted (but + failed) to access DECL. + + Examine the parent binfos of BINFO and determine whether any of them had + private access to DECL. If they did, return the parent binfo. This helps + in figuring out the correct error message to show (if the parents had + access, it's their fault for not giving sufficient access to BINFO). + + If no parents had access, return NULL_TREE. */ + +tree +get_parent_with_private_access (tree decl, tree binfo) +{ + /* Only BINFOs should come through here. */ + gcc_assert (TREE_CODE (binfo) == TREE_BINFO); + + tree base_binfo = NULL_TREE; + + /* Iterate through immediate parent classes. */ + for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + /* This parent had private access. Therefore that's why BINFO can't + access DECL. */ + if (access_in_type (BINFO_TYPE (base_binfo), decl) == ak_private) + return base_binfo; + } + + /* None of the parents had access. Note: it's impossible for one of the + parents to have had public or protected access to DECL, since then + BINFO would have been able to access DECL too. */ + return NULL_TREE; +} + /* Returns true if type BASE is accessible in T. (BASE is known to be a (possibly non-proper) base class of T.) If CONSIDER_LOCAL_P is true, consider any special access of the current scope, or access |