This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ Patch] PR 35331
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 10 May 2008 22:49:38 +0200
- Subject: Re: [C++ Patch] PR 35331
- References: <48024203.5020305@suse.de> <48151F9C.5070707@codesourcery.com>
Hi Mark, all,
This is the sort of situation where I think we should be much more
brutal.
+ template<typename...> struct A;
+ + template<typename...T> struct A<T*> // { dg-error "not expanded|T" }
+ { // { dg-error "not expanded|T" }
+ friend void foo();
+ };
Rather than trying to make add_friend -- and every other function that
might be called as we try to build up members of a erroneous class --
we should short-circuit the whole process. I would suggest we just
skip everything inside the erroneous class -- look for the matching
closing brace and be done with it. That will no doubt eliminate a
bunch of crashses, making the compiler more robust. The downside, of
course, is that the user may not get errors about things within the
erroneous class until they fix the class -- but with a class that
makes no sense, it's not clear that there's a whole lot in there we
can be intelligent about.
Below you will find my second try, which tries to implement your
suggestions. Tested x86_64-linux.
What do you think?
Thanks,
Paolo.
/////////////////
/cp
2008-05-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/35331
* parser.c (cp_parser_class_specifier): Extend checks on the type
returned by begin_class_definition.
/testsuite
2008-05-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/35331
* g++.dg/cpp0x/vt-35331.C: New.
* g++.dg/cpp0x/vt-34055.C: Adjust.
* g++.dg/cpp0x/vt-34606.C: Likewise.
* g++.dg/cpp0x/pr32125.C: Likewise.
* g++.dg/cpp0x/pr31438.C: Likewise.
Index: testsuite/g++.dg/cpp0x/vt-34055.C
===================================================================
*** testsuite/g++.dg/cpp0x/vt-34055.C (revision 135153)
--- testsuite/g++.dg/cpp0x/vt-34055.C (working copy)
*************** template<typename...> struct A;
*** 4,10 ****
template<typename...T> struct A<T*> // { dg-error "parameter packs|T" }
{ // { dg-error "parameter packs|T" }
! void foo(); // { dg-error "parameter packs|T|candidate" }
};
template<typename...T> void A<T*>::foo() {} // { dg-error "invalid declarator" }
--- 4,10 ----
template<typename...T> struct A<T*> // { dg-error "parameter packs|T" }
{ // { dg-error "parameter packs|T" }
! void foo();
};
template<typename...T> void A<T*>::foo() {} // { dg-error "invalid declarator" }
*************** template<typename...> struct B;
*** 15,21 ****
template<typename...T> struct B<T&> // { dg-error "parameter packs|T" }
{ // { dg-error "parameter packs|T" }
! void foo(); // { dg-error "parameter packs|T" }
};
template<typename...T> void B<T&>::foo() {} // { dg-error "invalid declarator" }
--- 15,21 ----
template<typename...T> struct B<T&> // { dg-error "parameter packs|T" }
{ // { dg-error "parameter packs|T" }
! void foo();
};
template<typename...T> void B<T&>::foo() {} // { dg-error "invalid declarator" }
*************** template<typename...> struct C;
*** 25,31 ****
template<typename...T> struct C<T()> // { dg-error "parameter packs|T" }
{ // { dg-error "parameter packs|T" }
! void foo(); // { dg-error "parameter packs|T" }
};
template<typename...T> void C<T()>::foo() {} // { dg-error "invalid declarator" }
--- 25,31 ----
template<typename...T> struct C<T()> // { dg-error "parameter packs|T" }
{ // { dg-error "parameter packs|T" }
! void foo();
};
template<typename...T> void C<T()>::foo() {} // { dg-error "invalid declarator" }
Index: testsuite/g++.dg/cpp0x/vt-35331.C
===================================================================
*** testsuite/g++.dg/cpp0x/vt-35331.C (revision 0)
--- testsuite/g++.dg/cpp0x/vt-35331.C (revision 0)
***************
*** 0 ****
--- 1,7 ----
+ // { dg-options "-std=c++0x" }
+ template<typename...> struct A;
+
+ template<typename...T> struct A<T*> // { dg-error "not expanded|T" }
+ { // { dg-error "not expanded|T" }
+ friend void foo();
+ };
Index: testsuite/g++.dg/cpp0x/vt-34606.C
===================================================================
*** testsuite/g++.dg/cpp0x/vt-34606.C (revision 135153)
--- testsuite/g++.dg/cpp0x/vt-34606.C (working copy)
*************** template<typename T, typename... U> stru
*** 5,9 ****
{ // { dg-error "parameter packs|U" }
template<typename> struct B;
! template<typename X> struct B<X*> {}; // { dg-error "parameter packs|U" }
};
--- 5,9 ----
{ // { dg-error "parameter packs|U" }
template<typename> struct B;
! template<typename X> struct B<X*> {};
};
Index: testsuite/g++.dg/cpp0x/pr32125.C
===================================================================
*** testsuite/g++.dg/cpp0x/pr32125.C (revision 135153)
--- testsuite/g++.dg/cpp0x/pr32125.C (working copy)
*************** template<typename...> struct A;
*** 3,8 ****
template<typename...T> struct A<T*> // { dg-error "not expanded|T" }
{ // { dg-error "not expanded|T" }
! A(); // { dg-error "not expanded|T" }
! A(T); // { dg-error "not expanded|T" }
};
--- 3,8 ----
template<typename...T> struct A<T*> // { dg-error "not expanded|T" }
{ // { dg-error "not expanded|T" }
! A();
! A(T);
};
Index: testsuite/g++.dg/cpp0x/pr31438.C
===================================================================
*** testsuite/g++.dg/cpp0x/pr31438.C (revision 135153)
--- testsuite/g++.dg/cpp0x/pr31438.C (working copy)
***************
*** 3,9 ****
template<typename> struct A;
template<typename T, typename... U> struct A<T(U)> // { dg-error "parameter packs|U" }
{ // { dg-error "parameter packs|U" }
! template<typename X> A(X); // { dg-error "parameter packs|U" }
};
A<void(int)> a(0); // { dg-error "incomplete type" }
--- 3,9 ----
template<typename> struct A;
template<typename T, typename... U> struct A<T(U)> // { dg-error "parameter packs|U" }
{ // { dg-error "parameter packs|U" }
! template<typename X> A(X);
};
A<void(int)> a(0); // { dg-error "incomplete type" }
Index: cp/parser.c
===================================================================
*** cp/parser.c (revision 135153)
--- cp/parser.c (working copy)
*************** cp_parser_class_specifier (cp_parser* pa
*** 14420,14426 ****
}
type = begin_class_definition (type, attributes);
! if (type == error_mark_node)
/* If the type is erroneous, skip the entire body of the class. */
cp_parser_skip_to_closing_brace (parser);
else
--- 14420,14426 ----
}
type = begin_class_definition (type, attributes);
! if (type == error_mark_node || error_operand_p (TYPE_MAIN_DECL (type)))
/* If the type is erroneous, skip the entire body of the class. */
cp_parser_skip_to_closing_brace (parser);
else