Bug 49042 - [C++0x] wrong "protected" when using template and decltype
Summary: [C++0x] wrong "protected" when using template and decltype
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: 4.6.1
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2011-05-18 10:28 UTC by Wei Tao
Modified: 2011-05-25 01:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-05-18 11:30:27


Attachments
the preprocessed file of tmpl_decl.cpp (331 bytes, application/octet-stream)
2011-05-18 10:28 UTC, Wei Tao
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Wei Tao 2011-05-18 10:28:50 UTC
Created attachment 24282 [details]
the preprocessed file of tmpl_decl.cpp

preprocessed file is in the attachment.

the source code is shown as below:
==========================================================================
template<typename T> class W{
protected:
	T* p;

public:
	W()
	{
		p=new T();
	}

	~W()
	{
		if(p)
			delete p;
	}

	auto test1(int i) -> decltype(p->get(i))
	{
		return p->get(i);
	}

	template<typename Ta>int test2(Ta&& i)
	{
		return p->get(i);
	}
	
#if 1// bug in g++ 4.4, 4.5 & 4.6
#define TESTCASE3
	template<typename Ta>auto test3(Ta&& i) -> decltype(p->get(i))
	{
		return p->get(i);
	}
#endif

#if 1 // bug in g++ 4.4 & 4.5
#define TESTCASE4
	// this is an ugly workground for 4.6
	template<typename Ta>auto test4(Ta&& i) -> decltype(((T*)0)->get(i))
	{
		return p->get(i);
	}
#endif
};

class A;

typedef W<A> B;

class A{
protected:
	int _i;
public:
	A():_i(0)
	{}

	A(int i):_i(i)
	{}

	int get(int i)const
	{
		return _i-i;
	}

};

int main()
{
	int s;
	B b;
	s+=b.test1(0);
	s+=b.test2(0);
	
#ifdef TESTCASE3
	s+=b.test3(0);
#endif
	
#ifdef TESTCASE4
	s+=b.test4(0);
#endif
	return s;
}
==========================================================================
While test1(), test2() are all ok for g++ -std=c++0x from 4.4 to 4.6,
test3() is rejected by all, and test4() is accepted only by 4.6.

G++4.6 gives a strange error message for test3() such as "tmpl_decl.cpp:3:5: error: ‘A* W<A>::p’ is protected", while it accepts "p" in test1().

btw, g++ 4.4, 4.5 both reject test3() and test4() with other error messages, so this is not a regression error.

output of "g++ -v -save-temps -std=c++0x -c tmpl_decl.cpp"
==========================================================================
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.6.0-3~ppa1' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/x86_64-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib/x86_64-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 20110409 (prerelease) (Ubuntu 4.6.0-3~ppa1) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++0x' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/cc1plus -E -quiet -v -D_GNU_SOURCE tmpl_decl.cpp -mtune=generic -march=x86-64 -std=c++0x -fpch-preprocess -fstack-protector -o tmpl_decl.ii
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/../../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/4.6
 /usr/include/c++/4.6/x86_64-linux-gnu
 /usr/include/c++/4.6/backward
 /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/include
 /usr/local/include
 /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++0x' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/cc1plus -fpreprocessed tmpl_decl.ii -quiet -dumpbase tmpl_decl.cpp -mtune=generic -march=x86-64 -auxbase tmpl_decl -std=c++0x -version -fstack-protector -o tmpl_decl.s
GNU C++ (Ubuntu 4.6.0-3~ppa1) version 4.6.1 20110409 (prerelease) (x86_64-linux-gnu)
        compiled by GNU C version 4.6.1 20110409 (prerelease), GMP version 4.3.2, MPFR version 3.0.0-p8, MPC version 0.9
GGC heuristics: --param ggc-min-expand=63 --param ggc-min-heapsize=62982
GNU C++ (Ubuntu 4.6.0-3~ppa1) version 4.6.1 20110409 (prerelease) (x86_64-linux-gnu)
        compiled by GNU C version 4.6.1 20110409 (prerelease), GMP version 4.3.2, MPFR version 3.0.0-p8, MPC version 0.9
GGC heuristics: --param ggc-min-expand=63 --param ggc-min-heapsize=62982
Compiler executable checksum: 9b2d061a0b3f0ab5a4eef825b71a3b00
tmpl_decl.cpp: In function ‘int main()’:
tmpl_decl.cpp:3:5: error: ‘A* W<A>::p’ is protected
tmpl_decl.cpp:74:14: error: within this context
==========================================================================
Comment 1 Jonathan Wakely 2011-05-18 11:30:27 UTC
possibly related to PR 48884 and PR 49003
Comment 2 Jason Merrill 2011-05-24 23:45:05 UTC
Author: jason
Date: Tue May 24 23:44:59 2011
New Revision: 174151

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174151
Log:
	PR c++/49042
	* pt.c (get_mostly_instantiated_function_type): Use
	push_deferring_access_checks rather than set flag_access_control.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/access01.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog
Comment 3 Jason Merrill 2011-05-25 01:08:55 UTC
Author: jason
Date: Wed May 25 01:08:53 2011
New Revision: 174164

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174164
Log:
	PR c++/49042
	* pt.c (get_mostly_instantiated_function_type): Use
	push_deferring_access_checks rather than set flag_access_control.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/access01.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/pt.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 4 Jason Merrill 2011-05-25 01:12:31 UTC
Fixed for 4.6.1.