[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2022-06-02 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Patrick Palka  changed:

   What|Removed |Added

 CC||csaba_22 at yahoo dot co.uk

--- Comment #12 from Patrick Palka  ---
*** Bug 105752 has been marked as a duplicate of this bug. ***

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2022-05-15 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

--- Comment #11 from CVS Commits  ---
The master branch has been updated by Jason Merrill :

https://gcc.gnu.org/g:4df735e01e319997841574f353d2aa076a0335c2

commit r13-465-g4df735e01e319997841574f353d2aa076a0335c2
Author: Jason Merrill 
Date:   Fri Mar 18 22:52:32 2022 -0400

c++: hidden friend access [DR1699]

It has come up several times that Clang considers hidden friends of a class
to be sufficiently memberly to be covered by a friend declaration naming
the
class.  This is somewhat unclear in the standard: [class.friend] says
"Declaring a class to be a friend implies that private and protected
members
of the class granting friendship can be named in the base-specifiers and
member declarations of the befriended class."

A hidden friend is a syntactic member-declaration, but is it a "member
declaration"?  CWG was ambivalent, and referred the question to EWG as a
design choice.  But recently Patrick mentioned that the current G++ choice
not to treat it as a "member declaration" was making his library work
significantly more cumbersome, so let's go ahead and vote the other way.

This means that the testcases for 100502 and 58993 are now accepted.

DR1699
PR c++/100502
PR c++/58993

gcc/cp/ChangeLog:

* friend.cc (is_friend): Hidden friends count as members.
* search.cc (friend_accessible_p): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/template/access37.C: Now OK.
* g++.dg/template/friend69.C: Now OK.
* g++.dg/lookup/friend23.C: New test.

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2021-01-20 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Patrick Palka  changed:

   What|Removed |Added

   Target Milestone|--- |11.0
 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED

--- Comment #10 from Patrick Palka  ---
Fixed for GCC 11.

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2021-01-19 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

--- Comment #9 from CVS Commits  ---
The master branch has been updated by Patrick Palka :

https://gcc.gnu.org/g:29853c653245c37ed31b6abcc9799b534372e938

commit r11-6800-g29853c653245c37ed31b6abcc9799b534372e938
Author: Patrick Palka 
Date:   Tue Jan 19 16:20:00 2021 -0500

c++: Always check access during late-parsing of members [PR58993]

This patch removes a vestigial use of dk_no_check from
cp_parser_late_parsing_for_member, which ideally should have been
removed as part of the PR41437 patch that improved access checking
inside templates.  This allows us to correctly reject f1 and f2 in
the testcase access34.C below (whereas before we'd only reject f3).

Additional testing revealed a new access issue when late-parsing a hidden
friend within a class template.  In the testcase friend68.C below, we're
tripping over the checking assert from friend_accessible_p(f, S::j, S, S)
during lookup of j in x.j (for which type_dependent_object_expression_p
returns false, which is why we're doing the lookup at parse time).  The
reason for the assert failure is that DECL_FRIENDLIST(S) contains f but
DECL_BEFRIENDING_CLASSES(f) is empty, and so friend_accessible_p (which
looks at DECL_BEFRIENDING_CLASSES) wants to return false, but is_friend
(which looks at DECL_FRIENDLIST) returns true.

For sake of symmetry one would expect that DECL_BEFRIENDING_CLASSES(f)
contains S, but add_friend avoids updating DECL_BEFRIENDING_CLASSES when
the class type (S in this case) is dependent, for some reason.

This patch works around this issue by making friend_accessible_p
consider the DECL_FRIEND_CONTEXT of the access scope.  Thus we sidestep
the DECL_BEFRIENDING_CLASSES / DECL_FRIENDLIST asymmetry issue while
correctly validating the x.j access at parse time.

A earlier version of this patch checked friend_accessible_p instead of
protected_accessible_p in the DECL_FRIEND_CONTEXT hunk below, but this
had the side effect of making us accept the ill-formed testcase friend69.C
below (ill-formed because the hidden friend g is not actually a member
of A, so g doesn't have access to B's members despite B befriending A).

gcc/cp/ChangeLog:

PR c++/41437
PR c++/58993
* search.c (friend_accessible_p): If scope is a hidden friend
defined inside a dependent class, consider access from the
class.
* parser.c (cp_parser_late_parsing_for_member): Don't push a
dk_no_check access state.

gcc/testsuite/ChangeLog:

PR c++/41437
PR c++/58993
* g++.dg/opt/pr87974.C: Adjust.
* g++.dg/template/access34.C: New test.
* g++.dg/template/friend68.C: New test.
* g++.dg/template/friend69.C: New test.

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2021-01-12 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Patrick Palka  changed:

   What|Removed |Added

 CC||ppalka at gcc dot gnu.org
 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |ppalka at gcc dot 
gnu.org

--- Comment #8 from Patrick Palka  ---
(In reply to Jonathan Wakely from comment #5)
> Warning-free testcase:
> 
> class base {
> private:
> void foo() { }
> };
> 
> template 
> struct bar : public base {
> void test() {
> (void) ::foo;  // should be rejected
> }
> };
> 
> template <>
> struct bar : public base {
> void test() {
> // ::foo;  // correctly rejected
> }
> };
> 
> int main() {
> bar().test();
> bar().test();
> }
> 
> Still accepted by trunk.
> 
> 
> Clang says:
> 
> 58993.cc:9:23: error: 'foo' is a private member of 'base'
> (void) ::foo;  // should be rejected
>   ^
> 58993.cc:3:10: note: declared private here
> void foo() { }
>  ^
> 1 error generated.
> 
> 
> and EDG says:
> 
> "58993.cc", line 9: error: function "base::foo" (declared at line 3) is
>   inaccessible
>   (void) ::foo;  // should be rejected
> ^
>   detected during instantiation of "void bar::test() [with T=int]"
> at line 21
> 
> 1 error detected in the compilation of "58993.cc".

With GCC 11 (after the PR41437 patch), we reject the first access only if
bar::test() is defined out-of-line:

class base {
private:
int foo() { }
};

template 
struct bar : public base {
void test();
};

template 
void bar::test() {
::foo;
}

int main() {
bar().test();
}

Investigating.

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2019-07-17 Thread dennis at felsin9 dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

dennis at felsin9 dot de  changed:

   What|Removed |Added

 CC||dennis at felsin9 dot de

--- Comment #7 from dennis at felsin9 dot de  ---
Another example, no warnings in G++ 9.1.0, fails in Clang++ as expected:

class C
{
struct Print
{
const class C& c;
};
};

template
struct D : public C
{
void create()
{
[[maybe_unused]] C::Print p{*this};
}
};

int main()
{
D d;
d.create();
}

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2018-05-28 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Jonathan Wakely  changed:

   What|Removed |Added

 CC||achuah at drwsg dot com

--- Comment #6 from Jonathan Wakely  ---
*** Bug 85943 has been marked as a duplicate of this bug. ***

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2018-02-27 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Jonathan Wakely  changed:

   What|Removed |Added

   Last reconfirmed|2013-11-05 00:00:00 |2018-2-27

--- Comment #5 from Jonathan Wakely  ---
Warning-free testcase:

class base {
private:
void foo() { }
};

template 
struct bar : public base {
void test() {
(void) ::foo;  // should be rejected
}
};

template <>
struct bar : public base {
void test() {
// ::foo;  // correctly rejected
}
};

int main() {
bar().test();
bar().test();
}

Still accepted by trunk.


Clang says:

58993.cc:9:23: error: 'foo' is a private member of 'base'
(void) ::foo;  // should be rejected
  ^
58993.cc:3:10: note: declared private here
void foo() { }
 ^
1 error generated.


and EDG says:

"58993.cc", line 9: error: function "base::foo" (declared at line 3) is
  inaccessible
  (void) ::foo;  // should be rejected
^
  detected during instantiation of "void bar::test() [with T=int]"
at line 21

1 error detected in the compilation of "58993.cc".

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2016-08-24 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Jonathan Wakely  changed:

   What|Removed |Added

 CC||albin.olsson at volvocars dot 
com

--- Comment #4 from Jonathan Wakely  ---
*** Bug 77368 has been marked as a duplicate of this bug. ***

[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2013-11-05 Thread redi at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

Jonathan Wakely redi at gcc dot gnu.org changed:

   What|Removed |Added

   Keywords||accepts-invalid
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2013-11-05
 Blocks||59002
Summary|failure to access pointer   |incorrectly accept access
   |to protected member method  |of protected member method
   |in base from derived class  |from derived class template
   |specialization  |
 Ever confirmed|0   |1

--- Comment #2 from Jonathan Wakely redi at gcc dot gnu.org ---
Reduced test, where the base member is private, but the primary template can
still access it

class base {
private:
int foo() { }
};

template typename T
struct bar : public base {
void test() {
base::foo;  // should be rejected
}
};

template 
struct barvoid : public base {
void test() {
// base::foo;  // correctly rejected
}
};

int main() {
barint().test();
barvoid().test();
}


[Bug c++/58993] incorrectly accept access of protected member method from derived class template

2013-11-05 Thread cvs at cs dot utoronto.ca
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58993

--- Comment #3 from Chris Studholme cvs at cs dot utoronto.ca ---
Ah, thanks for the info.  I thought I tried 'bar::foo' and it didn't work
without 'using base::foo'.  I just tried it again and it does work (in both
cases) without the using declaration so I must have made some other mistake
earlier.