This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
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 }
Created an attachment (id=17884) [edit] A candidate patch I am testing this patch at the moment. Could you please test it in your environment and tell me if it helps at all ? Thanks.
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
Fixed in trunk.
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