diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pseudodtor1.C | 44 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pseudodtor2.C | 18 |
5 files changed, 82 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c7946ac..51f219b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2007-11-01 Jakub Jelinek <jakub@redhat.com> + PR c++/32384 + * parser.c (cp_parser_postfix_dot_deref_expression): If + POSTFIX_EXPRESSION is type dependent, try to parse it as pseudo dtor + first and if that succeeds and type is SCALAR_TYPE_P, create + PSEUDO_DTOR_EXPR. + PR c++/32260 * rtti.c (enum_tinfo_kind): Fix TK_TYPE_INFO_TYPE comment. (typeid_ok_p): Use the same alias set for abi::__type_info_pseudo diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2b73a85..7734cc1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4850,8 +4850,10 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, pseudo_destructor_p = false; /* If the SCOPE is a scalar type, then, if this is a valid program, - we must be looking at a pseudo-destructor-name. */ - if (scope && SCALAR_TYPE_P (scope)) + we must be looking at a pseudo-destructor-name. If POSTFIX_EXPRESSION + is type dependent, it can be pseudo-destructor-name or something else. + Try to parse it as pseudo-destructor-name first. */ + if ((scope && SCALAR_TYPE_P (scope)) || dependent_p) { tree s; tree type; @@ -4860,7 +4862,12 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, /* Parse the pseudo-destructor-name. */ s = NULL_TREE; cp_parser_pseudo_destructor_name (parser, &s, &type); - if (cp_parser_parse_definitely (parser)) + if (dependent_p + && (cp_parser_error_occurred (parser) + || TREE_CODE (type) != TYPE_DECL + || !SCALAR_TYPE_P (TREE_TYPE (type)))) + cp_parser_abort_tentative_parse (parser); + else if (cp_parser_parse_definitely (parser)) { pseudo_destructor_p = true; postfix_expression diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 74c7230..849f07e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2007-11-01 Jakub Jelinek <jakub@redhat.com> + PR c++/32384 + * g++.dg/template/pseudodtor1.C: New test. + * g++.dg/template/pseudodtor2.C: New test. + PR c++/32260 * g++.dg/rtti/typeid7.C: New test. diff --git a/gcc/testsuite/g++.dg/template/pseudodtor1.C b/gcc/testsuite/g++.dg/template/pseudodtor1.C new file mode 100644 index 0000000..cf7c254 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor1.C @@ -0,0 +1,44 @@ +// PR c++/32384 +// { dg-do compile } + +struct A +{ + typedef int T; + T foo (); + + A () { foo ().~T (); } +}; + +template<typename> struct B +{ + typedef int T; + T foo (); + + B () { foo ().~T (); } +}; + +template<typename T> struct C +{ + T t; + C () { t.~T (); } +}; + +template<typename S> struct D +{ + typedef int T; + S foo (); + + D () { foo ().~T(); } +}; + +struct Z +{ + Z () {} + ~Z () {} +}; + +A a; +B<int> b; +C<int> c1; +C<Z> c2; +D<int> d; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor2.C b/gcc/testsuite/g++.dg/template/pseudodtor2.C new file mode 100644 index 0000000..796aff0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor2.C @@ -0,0 +1,18 @@ +// PR c++/32384 +// { dg-do compile } + +template<typename S> struct D +{ + typedef int T; + S foo (); + + D () { foo ().~T(); } // { dg-error "is not of type" } +}; + +struct Z +{ + Z () {} + ~Z () {} +}; + +D<Z> d; |