Bug 14281 - Regression in v3.4: friend class not working
Summary: Regression in v3.4: friend class not working
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-02-25 00:52 UTC by Niall Douglas
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Preprocessor output illustrating the bug (maybe) (71.95 KB, application/octet-stream)
2004-02-25 00:53 UTC, Niall Douglas
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Niall Douglas 2004-02-25 00:52:21 UTC
With GCC v3.4 CVS 20040218 it thinks that ImplBase (typedefed within its parent) 
is private which it is - but the class which inherits off of it via template 
parameter is a friend.

I understand that friendship may not apply to base classes as it's not 
technically "in" the class yet. However my outdated version of the standard 
isn't clear here so I have no real way of knowing except that MSVC and GCC v3.2 
compile this fine.

g++ -fPIC -Wformat -Wno-reorder -Wno-non-virtual-dtor -march=i486 
-mcpu=athlon-xp -fexceptions -fkeep-inline-functions -g -DFOXDLL -DUSE_POSIX 
-DHAVE_CONSTTEMPORARIES -D_DEBUG -DHAVE_XSHM_H -DHAVE_XCURSOR_H=1 -DHAVE_XFT_H=1 
-DXTHREADS=1 -DFOX_THREAD_SAFE=1 -DHAVE_LIBDL=1 -DHAVE_CUPS_H=1 -DSTDC_HEADERS=1 
-DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 
-DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 
-DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_WAIT_H=1 
-DHAVE_DIRENT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_SELECT_H=1 
-DBUILDING_TCOMMON -DFOXDLL_EXPORTS -DHAVE_JPEG_H -DHAVE_PNG_H -DHAVE_TIFF_H 
-DHAVE_ZLIB_H -DHAVE_OPENSSL -DHAVE_GL_H -DSUN_OGL_NO_VERTEX_MACROS 
-DHPOGL_SUPPRESS_FAST_API -DHAVE_GLU_H -ITnFOX/include -I/usr/kerberos/include 
-I/usr/X11R6/include -I/usr/include/freetype2 -Iinclude -c -o 
objs/Debug/TFileBySyncDev.os src/TFileBySyncDev.cxx
`-mcpu=' is deprecated. Use `-mtune=' or '-march=' instead.
src/TFileBySyncDev.cxx: In member function `FX::FXIPCChannel::HandledCode Tn::
TFileBySyncDevPrivate::msgReceived(FX::FXIPCMsg*)':
src/TFileBySyncDev.cxx:260: warning: converting of negative value `-0x000000001' 
to `unsigned int'
TnFOX/include/FXGenericTools.h: At global scope:
TnFOX/include/FXGenericTools.h: In instantiation of `FX::Generic::FunctorHelper:
:ImplMemFn<FX::Generic::Functor<FX::Generic::TL::item<FX::FXIPCChannel::
HandledCode, FX::Generic::TL::item<FX::FXIPCMsg*, FX::Generic::NullType> > >, 
Tn::TFileBySyncDevPrivate, FX::FXIPCChannel::HandledCode (Tn::
TFileBySyncDevPrivate::*)(FX::FXIPCMsg*)>':
TnFOX/include/FXGenericTools.h:1259:   instantiated from `FX::Generic::
Functor<parslist>::Functor(obj*, fn) [with obj = Tn::TFileBySyncDevPrivate, fn = 
FX::FXIPCChannel::HandledCode (Tn::TFileBySyncDevPrivate::*)(FX::FXIPCMsg*), 
parslist = FX::Generic::TL::item<FX::FXIPCChannel::HandledCode, FX::Generic::TL:
:item<FX::FXIPCMsg*, FX::Generic::NullType> >]'
src/TFileBySyncDev.cxx:297:   instantiated from here
TnFOX/include/FXGenericTools.h:1240: error: `typedef struct FX::Generic::
FunctorHelper::ImplBaseOp<FX::Generic::TL::item<FX::FXIPCChannel::HandledCode, 
FX::Generic::TL::item<FX::FXIPCMsg*, FX::Generic::NullType> >, 1> FX::Generic::
Functor<FX::Generic::TL::item<FX::FXIPCChannel::HandledCode, FX::Generic::TL::
item<FX::FXIPCMsg*, FX::Generic::NullType> > >::ImplBase' is private
TnFOX/include/FXGenericTools.h:1195: error: within this context
scons: *** [objs/Debug/TFileBySyncDev.os] Error 1

Cheers,
Niall
Comment 1 Niall Douglas 2004-02-25 00:53:53 UTC
Created attachment 5793 [details]
Preprocessor output illustrating the bug (maybe)
Comment 2 Giovanni Bajo 2004-02-25 01:56:44 UTC
Since you seem to know what's going on, maybe you can help us and provide a 
minimal snippet showing the problem?
Comment 3 Volker Reichelt 2004-02-25 02:22:39 UTC
Here's a minimal testcase showing the problem.
I guess, gcc is actually right when rejecting the code
(it does so since 3.3), but I'm not sure.

=====================================================
template <typename T> struct A : public T::X {};

class B
{
    template <typename> friend class A;
    struct X {};
};

A<B> a;
=====================================================
Comment 4 Niall Douglas 2004-02-25 03:29:30 UTC
(In reply to comment #3)
> Here's a minimal testcase showing the problem.
> I guess, gcc is actually right when rejecting the code
> (it does so since 3.3), but I'm not sure.
> 
> =====================================================
> template <typename T> struct A : public T::X {};
> 
> class B
> {
>     template <typename> friend class A;
>     struct X {};
> };
> 
> A<B> a;
> =====================================================
> 

This is it in one. Now seeing as you guys are the experts, does inheriting off 
something observe that something's friend rules? ie; does the class begin before 
inheriting or after?

I should add I tested against v3.2 where it does work, not v3.3 which dies with 
certain code sequences in my code so I tend to avoid it (v3.4 has them fixed so 
I haven't reported these).

Cheers,
Niall
Comment 5 Andrew Pinski 2004-02-25 04:44:22 UTC
This is not a bug, ICC 6.0 rejects this code (but only when strict mode is turned on):
pr14281.cc
pr14281.cc(1): error #308: class "B::X" is inaccessible
  template <typename T> struct A : public T::X {};
                                             ^
          detected during instantiation of class "A<T> [with T=B]" at line 9

compilation aborted for pr14281.cc (code 2)
Comment 6 Giovanni Bajo 2004-02-25 15:03:32 UTC
Well, ICC/EDG might be wrong, especially if you use such an old version. 
Please, let's not close bugs only because another compiler behaves differently, 
even if it's EDG. 

Anyway, this bug is indeed invalid because of [class.friend]/2 in the C++ 
Standard, which says: "Also, because the base-clause of the friend class is not 
part of its member declarations, the base-clause of the friend class cannot 
access the names of the private and protected members from the class granting 
friendship."

So GCC is indeed correct.
Comment 7 Gabriel Dos Reis 2004-02-25 15:18:55 UTC
Subject: Re:  Regression in v3.4: friend class not working

"giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes:


| Please, let's not close bugs only because another compiler behaves
| differently, even if it's EDG. 

Amen.  I wish we do not end up being a clone of EDG (I do intend to
diminish their values) or do whatever EDG does.

-- Gaby