Bug 38579 - [4.2/4.3/4.4 Regression] Template: Wrong inherited copy-ctor visibility
Summary: [4.2/4.3/4.4 Regression] Template: Wrong inherited copy-ctor visibility
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.2
: P2 normal
Target Milestone: 4.2.5
Assignee: Jason Merrill
URL:
Keywords: accepts-invalid
: 35640 (view as bug list)
Depends on:
Blocks: 66957
  Show dependency treegraph
 
Reported: 2008-12-19 13:00 UTC by Peter Kümmel
Modified: 2015-08-20 02:07 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3
Known to fail: 3.4.6, 4.0.0, 4.3.0, 4.4.0
Last reconfirmed: 2009-01-16 06:42:05


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Kümmel 2008-12-19 13:00:09 UTC
The code below compiles, but it should give an error, because the Policy ctor is not accessible when inheriting protected from Policy 
To have valid C++ code the inheritance must be public.


struct Policy
{
protected:
	Policy() {}
	Policy(const Policy&) {}
};

template<int I, class P>
struct BugGcc :
	protected P
	//public P
{
	BugGcc() {}

	template<int I, class P>
	BugGcc(const BugGcc<I, P>& t) : P(t) {}
};

void foo()
{
	BugGcc<0, Policy> f1;
	BugGcc<1, Policy> f2(f1);
}


GCC:
gcc-Version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC)
Comment 1 Andrew Pinski 2008-12-21 23:10:27 UTC
Confirmed, related to PR 26693.

Here is the correct testcase (the testcase below does not compile with 4.4 but for a different reason than the real bug):
struct Policy
{
protected:
        Policy() {}
        Policy(const Policy&) {}
};

template<int I, class P>
struct BugGcc :
        protected P
        //public P
{
        BugGcc() {}

        template<int I1, class P1>
        BugGcc(const BugGcc<I1, P1>& t) : P(t) {}
};

void foo()
{
        BugGcc<0, Policy> f1;
        BugGcc<1, Policy> f2(f1);
}
Comment 2 Jason Merrill 2009-01-14 16:37:33 UTC
11.2:                                                                                      If a class is declared to be a base class for another class using the protected access specifier, the public and protected members of the base class are accessible as protected members of the derived class.

Not a bug.
Comment 3 Peter Kümmel 2009-01-14 18:29:11 UTC
11.2 is talking about a different case.

When you instantiate the integer template parameter manually you will see that it is really a bug:

struct Policy
{
protected:
    Policy() {}
    Policy(const Policy&) {}
};


template<class P>
struct BugGcc0 :
        protected P
        //public P
{
    BugGcc0() {}
};


template<class P>
struct BugGcc1 : public P
{
    BugGcc1() {}

    template<class P1>
    BugGcc1(const BugGcc0<P1>& t) : P(t) {}
};

void foo()
{
    BugGcc0<Policy> d0;
    BugGcc1<Policy> d1(d0);
}


The Policy ctor is visible within BugGcc1 (because it is inherited protected)
but it is not visible to a different class (again, because it is inherited protected).

BugGcc0 and BugGcc1 only have the same base class but they are NOT of same type which 11.2 talks about.

The protected policy ctor is only visible for BugGcc0 but not for BugGcc1.
Comment 4 Peter Kümmel 2009-01-15 18:56:24 UTC
It has nothing to do with templates.

This code still compiles:

struct P 
{
protected:
    P() {}
    P(const P&) {}
};

struct B : protected P
{
    B() {}
};

struct C : public P
{
    C(const B& b) : P(b) {}
};

void foo()
{
    B b;
    C c(b);
	
    //P p(b); // <-- compiler error
}

But I it should not, because only within the scope of B
B "is a" P. Globally B "is not a" P. Therefore you can't pass
a instance of B in a scope different to B to the constructor 
of P. 
Even when C inherits from P the struct B is still "not a" P
in the scope of C.
Comment 5 Jason Merrill 2009-01-16 06:17:25 UTC
Ah yes, I see.  The bug is not with the visibility of the copy ctor, but with the conversion from B to P in order to call it.
Comment 6 Jason Merrill 2009-01-16 06:41:53 UTC
This bug was introduced by the fix for PR 10990.
Comment 7 Jason Merrill 2009-01-16 18:35:41 UTC
Subject: Bug 38579

Author: jason
Date: Fri Jan 16 18:35:28 2009
New Revision: 143439

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143439
Log:
        PR c++/38579
        * search.c (protected_accessible_p): N doesn't vary.

Added:
    trunk/gcc/testsuite/g++.dg/conversion/access1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/search.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Jason Merrill 2009-01-16 18:55:13 UTC
Fixed for 4.4, not applying to older branches.
Comment 9 Jason Merrill 2009-01-16 18:58:08 UTC
*** Bug 35640 has been marked as a duplicate of this bug. ***
Comment 10 Jason Merrill 2015-08-20 02:07:19 UTC
Note that this will be broken again in 4.9.4 and 5.3, because the fix caused the worse bug 66957 and so I reverted it on those branches.  6.0 will have a proper fix.