109 lines
2.5 KiB
Diff
109 lines
2.5 KiB
Diff
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.
|
|
|
|
* g++.dg/template/pseudodtor1.C: New test.
|
|
* g++.dg/template/pseudodtor2.C: New test.
|
|
|
|
--- gcc/cp/parser.c (revision 129835)
|
|
+++ gcc/cp/parser.c (revision 129836)
|
|
@@ -4850,8 +4850,10 @@ cp_parser_postfix_dot_deref_expression (
|
|
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 (
|
|
/* 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
|
|
--- gcc/testsuite/g++.dg/template/pseudodtor1.C (revision 0)
|
|
+++ gcc/testsuite/g++.dg/template/pseudodtor1.C (revision 129836)
|
|
@@ -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;
|
|
--- gcc/testsuite/g++.dg/template/pseudodtor2.C (revision 0)
|
|
+++ gcc/testsuite/g++.dg/template/pseudodtor2.C (revision 129836)
|
|
@@ -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;
|