Bug 40007 - [4.5 regression] specialization causes access problem in primary template
|
Bug#:
40007
|
Product: gcc
|
Version: 4.5.0
|
|
Host:
|
Target:
|
Build:
|
|
Status: RESOLVED
|
Severity: normal
|
Priority: P1
|
|
Resolution: FIXED
|
Assigned To: dodji@gcc.gnu.org
|
Reported By: jwakely.gcc@gmail.com
|
|
Component: c++
|
Target Milestone: 4.5.0
|
|
Summary: [4.5 regression] specialization causes access problem in primary template
|
|
Keywords: rejects-valid
|
|
Opened: 2009-05-02 19:52
|
|
Description:
|
Last confirmed: 2009-05-13 21:53
|
Opened: 2009-05-02 19:52
|
template<typename T>
struct x
{
protected:
typedef int type;
};
template<typename T>
struct y : public x<T>
{
typedef x<T> base_type;
typedef typename base_type::type type;
};
template<>
struct y<void> : public x<void>
{
typedef x<void> base_type;
typedef base_type::type type;
};
template class y<int>;
int main()
{
return 0;
}
$ g++4x spec.cc
spec.cc: In instantiation of ‘y<int>’:
spec.cc:22: instantiated from here
spec.cc:5: error: ‘typedef int x<void>::type’ is protected
spec.cc:10: error: within this context
$ g++4x -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.x/configure --prefix=/home/redi/gcc/4.x
--with-system-zlib --enable-__cxa_atexit --with-arch=k8
--enable-libstdcxx-debug --disable-libstdcxx-pch --enable-languages=c,c++
--enable-libstdcxx-time=yes --disable-bootstrap --enable-checking=release
Thread model: posix
gcc version 4.5.0 20090502 (experimental) (GCC)
If the base class is not a template there is no error, if the y<void>
specialisation is not defined there is no error. As I'm not using the y<void>
specialisation, its contents should make no difference to the instantiation of
y<int>.
Looks like a regression since 4.3 as it works with gcc version 4.3.2 20081105
(Red Hat 4.3.2-7) (GCC) and Comeau's online compiler.
Only fails in trunk. I haven't checked, but could it be caused by the fix for
PR26693 ?
gcc-4.5-20090327 works, gcc-4.5-20090402 doesn't
Debugging cc1plus for this slightly reduced program:
template<typename T>
struct x
{
protected:
typedef int type;
};
template<typename T>
struct y : public x<T>
{
typename x<T>::type z;
};
template<>
struct y<void> : public x<void>
{
typedef x<void>::type z;
};
template class y<int>;
shows the explicit instantiation of y<int> calls
perform_typedefs_access_check() which calls
enforce_access() with decl = x<void>::type.
That's wrong, it should be x<int>::type - somehow the wrong typedef is
added to the list of types to check for the y<int> specialisation.
(gdb) bt
#0 enforce_access (basetype_path=0x2aaaab643180, decl=0x2aaaab641cc0,
diag_decl=0x2aaaab641cc0) at ../../src/gcc/gcc/cp/call.c:4447
#1 0x00000000004acabc in perform_typedefs_access_check (
tmpl=<value optimized out>, targs=0x2aaaab6429c0)
at ../../src/gcc/gcc/cp/pt.c:6960
#2 0x00000000004b827b in instantiate_class_template (type=0x2aaaab644240)
at ../../src/gcc/gcc/cp/pt.c:7443
#3 0x00000000004edf00 in complete_type (type=0x2aaaab644240)
at ../../src/gcc/gcc/cp/typeck.c:130
#4 0x00000000004b062c in do_type_instantiation (t=0x2aaaab644240,
storage=0x0, complain=1) at ../../src/gcc/gcc/cp/pt.c:15011
#5 0x00000000004e0f11 in cp_parser_explicit_instantiation (
parser=0x2aaaab4b59b0) at ../../src/gcc/gcc/cp/parser.c:10812
#6 0x00000000004e6905 in cp_parser_declaration (parser=0x2aaaab4b59b0)
at ../../src/gcc/gcc/cp/parser.c:8013
#7 0x00000000004e6caa in cp_parser_declaration_seq_opt (parser=0x2aaaab4b59b0)
at ../../src/gcc/gcc/cp/parser.c:7927
#8 0x00000000004e7527 in c_parse_file () at ../../src/gcc/gcc/cp/parser.c:3029
#9 0x00000000005557fa in c_common_parse_file (
set_yydebug=<value optimized out>) at ../../src/gcc/gcc/c-opts.c:1272
#10 0x00000000007519e2 in toplev_main (argc=13, argv=0x7fffffffe8a8)
at ../../src/gcc/gcc/toplev.c:979
#11 0x00002aaaaace24ca in __libc_start_main () from /lib/libc.so.6
#12 0x000000000048216a in _start () at ../sysdeps/x86_64/elf/start.S:113
(gdb) n
4448 gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
(gdb)
4450 if (!accessible_p (basetype_path, decl, true))
(gdb)
4452 if (TREE_PRIVATE (decl))
(gdb)
4454 else if (TREE_PROTECTED (decl))
(gdb)
4455 error ("%q+#D is protected", diag_decl);
(gdb)
pr40007.cc: In instantiation of ‘y<int>’:
pr40007.cc:20: instantiated from here
pr40007.cc:5: error: ‘typedef int x<void>::type’ is protected
4458 error ("within this context");
(gdb)
pr40007.cc:10: error: within this context
4463 }
By the way, here what I think is happening.
During the parsing of
template<>
struct y<void> : public x<void>
{
typedef x<void>::type z;
};
We detect that x<void>::type is a use of a typedef that is a member of the
class template x. We then wrongly append x<void>::type to the representation of
template<typename T> struct y so that we can perform access checks on the use
of x<void>::type once we instantiate y<void>. Later, during the instantiation
of template<typename T> struct y into y<int> we wrongly try to perform access
checks of x<void>::type even if x<void>::type has no business with the
instantiation of template<typename T> struct y;
In short, the typedef use x<void>::type should be added (for access checking
purposes) to the representation of the specialized template<> struct y<void>,
not to the representation of the most general template<typename T> struct y.
(In reply to comment #4)
> I am testing this patch at the moment.
> Could you please test it in your environment and tell me if it helps at all ?
Yes, that patch works for the code I was working on.
Subject: Bug 40007
Author: dodji
Date: Tue May 26 10:35:16 2009
New Revision: 147866
URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147866
Log:
Fix PR c++/40007
gcc/cp/ChangeLog:
PR c++/40007
* cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): Remove this accessor.
(TI_TYPEDEFS_NEEDING_ACCESS_CHECKING): New accessor.
(get_types_needing_access_check): Declare new entry point.
* pt.c (append_type_to_template_for_access_check_1,
get_types_needing_access_check): New functions.
(perform_typedefs_access_check): Accept FUNCTION_DECLs and
RECORD_TYPEs rather than TEMPLATE_DECLs. Use the new
get_types_needing_access_check, no more
MEMBER_TYPES_NEEDING_ACCESS_CHECK.
(instantiate_class_template): Set input_location to the source
location of the most specialized template definition.
Perform access check using the RECORD_TYPE of the template, not its
associated most generic TEMPLATE_DECL.
(append_type_to_template_for_access_check): Augment function
comments. Use the new get_types_needing_access_check, not
MEMBER_TYPE_NEEDING_ACCESS_CHECK. Use the new
append_type_to_template_for_access_check_1 subroutine.
gcc/testsuite/ChangeLog:
PR c++/40007
* g++.dg/template/typedef18.C: New test.
* g++.dg/template/typedef19.C: Likewise.
* g++.dg/template/typedef20.C: Likewise.
* g++.dg/template/access11.C: Adjust.
Added:
trunk/gcc/testsuite/g++.dg/template/typedef18.C
trunk/gcc/testsuite/g++.dg/template/typedef19.C
trunk/gcc/testsuite/g++.dg/template/typedef20.C
Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/cp-tree.h
trunk/gcc/cp/pt.c
trunk/gcc/testsuite/ChangeLog
trunk/gcc/testsuite/g++.dg/template/access11.C
Subject: Bug 40007
Author: hjl
Date: Sat May 30 13:49:33 2009
New Revision: 148004
URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=148004
Log:
2009-05-30 H.J. Lu <hongjiu.lu@intel.com>
Backport from mainline:
2009-05-28 Dodji Seketeli <dodji@redhat.com>
PR c++/39754
* g++.dg/template/canon-type-1.C: New test.
* g++.dg/template/canon-type-2.C: Likewise.
* g++.dg/template/canon-type-3.C: Likewise.
* g++.dg/template/canon-type-4.C: Likewise.
* g++.dg/template/canon-type-5.C: Likewise.
* g++.dg/template/canon-type-6.C: Likewise.
* g++.dg/template/canon-type-7.C: Likewise.
2009-05-28 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/40254
* gcc.dg/vect/pr40254.c: New test.
2009-05-26 Richard Guenther <rguenther@suse.de>
PR middle-end/40252
* gcc.c-torture/compile/pr40252.c: New testcase.
2009-05-26 Dodji Seketeli <dodji@redhat.com>
PR c++/40007
* g++.dg/template/typedef18.C: New test.
* g++.dg/template/typedef19.C: Likewise.
* g++.dg/template/typedef20.C: Likewise.
2009-05-25 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/40238
* gcc.dg/vect/pr40238.c: New test.
2009-05-24 Richard Guenther <rguenther@suse.de>
PR middle-end/40233
* gcc.c-torture/compile/pr40233.c: New testcase.
Added:
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-1.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-1.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-2.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-2.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-3.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-3.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-4.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-4.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-5.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-5.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-6.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-6.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/canon-type-7.C
- copied unchanged from r148002,
trunk/gcc/testsuite/g++.dg/template/canon-type-7.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/typedef18.C
- copied unchanged from r148003,
trunk/gcc/testsuite/g++.dg/template/typedef18.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/typedef19.C
- copied unchanged from r148003,
trunk/gcc/testsuite/g++.dg/template/typedef19.C
branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/typedef20.C
- copied unchanged from r148003,
trunk/gcc/testsuite/g++.dg/template/typedef20.C
branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr40233.c
- copied unchanged from r148003,
trunk/gcc/testsuite/gcc.c-torture/compile/pr40233.c
branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr40252.c
- copied unchanged from r148003,
trunk/gcc/testsuite/gcc.c-torture/compile/pr40252.c
branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/vect/pr40238.c
- copied unchanged from r148003,
trunk/gcc/testsuite/gcc.dg/vect/pr40238.c
branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/vect/pr40254.c
- copied unchanged from r148003,
trunk/gcc/testsuite/gcc.dg/vect/pr40254.c
Modified:
branches/gcc-4_4-branch/gcc/testsuite/ChangeLog