Bug 45917 - inaccessible types allowed as template argument in nested-name-specifier
Summary: inaccessible types allowed as template argument in nested-name-specifier
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.9.0
Assignee: Jason Merrill
URL:
Keywords: accepts-invalid
: 56687 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-10-06 21:20 UTC by Yuri
Modified: 2013-04-01 21:04 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-10-06 21:40:27


Attachments
patch (543 bytes, patch)
2013-03-14 21:40 UTC, Jason Merrill
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yuri 2010-10-06 21:20:06 UTC
testcase below has struct R as private in class F.
class F declares class Q a friend, allowing it to see it's private members.
But operator<< is friend in Q, not in F.
Why is it allowed for operator<< to instantiate list<R> but not R r? This is a bug.

--- testcase ---
#include <list>
#include <ostream>
using namespace std;

class F {
private:
  struct R {
  }; // R
  friend class Q;
  class Q {
    list<R> l;
    friend ostream& operator<<(ostream &os, const Q &q) {
      // R r; // this breaks!
      for (list<R>::const_iterator it = q.l.begin(); it != q.l.end(); it++) { // this doesn't break! Why?
      }
      return os;
    }
  }; // Q
}; // F
Comment 1 Jonathan Wakely 2010-10-06 21:40:27 UTC
(In reply to comment #0)
> class F declares class Q a friend

There's no need for that, Q is a member of F so has access like any other member.

Reduced:

template<class T>
struct list
{
  struct nested { };
};


class F
{
  struct R { };
  class Q
  {
    friend void f(const Q &q) { list<R>::nested n; }
  };
};
Comment 2 Jonathan Wakely 2010-10-06 21:48:01 UTC
Here's another variation that should fail but doesn't, showing this has nothing to do with friends:

template<class T>
struct list
{
  struct nested { };
};

class F
{
  struct R { };
};

void f() { list<F::R>::nested n; }

list<F::R>::nested n;


I've changed the summary to reflect this
Comment 3 Jason Merrill 2013-03-14 21:40:38 UTC
Created attachment 29671 [details]
patch

Simple fix, waiting for 4.8 to branch.
Comment 4 Jason Merrill 2013-03-17 02:39:39 UTC
Author: jason
Date: Sun Mar 17 02:39:22 2013
New Revision: 196744

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196744
Log:
	PR c++/45917
	* parser.c (cp_parser_template_id): Don't forget access checks.

Added:
    trunk/gcc/testsuite/g++.dg/template/access26.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
Comment 5 Paolo Carlini 2013-03-22 11:17:35 UTC
*** Bug 56687 has been marked as a duplicate of this bug. ***
Comment 6 Jason Merrill 2013-04-01 21:04:03 UTC
Fixed for 4.9.