Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > b5e52bbfb4bb11a6cbed452927fba979 > files > 59

gcc-4.1.2-50.el5.src.rpm

2008-02-13  Jakub Jelinek  <jakub@redhat.com>
	    Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

	PR c++/35138
	* parser.c (cp_parser_pseudo_destructor_name): If next tokens
	are not identifier :: ~, return before calling cp_parser_type_name.

2008-02-13  Jakub Jelinek  <jakub@redhat.com>

	PR c++/35138
	* g++.dg/template/member8.C: New test.

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
@@ -5164,24 +5164,26 @@ cp_parser_pseudo_destructor_name (cp_par
      additional qualification.  */
   else if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMPL))
     {
+      /* At this point, we're looking for "type-name :: ~".  The type-name
+	 must not be a class-name, since this is a pseudo-destructor.  So,
+	 it must be either an enum-name, or a typedef-name -- both of which
+	 are just identifiers.  So, we peek ahead to check that the "::"
+	 and "~" tokens are present; if they are not, then we can avoid
+	 calling type_name.  */
+      if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME
+	  || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE
+	  || cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_COMPL)
+	{
+	  cp_parser_error (parser, "non-scalar type");
+	  return;
+	}
+
       /* Look for the type-name.  */
       *scope = TREE_TYPE (cp_parser_type_name (parser));
 
       if (*scope == error_mark_node)
 	return;
 
-      /* If we don't have ::~, then something has gone wrong.  Since
-	 the only caller of this function is looking for something
-	 after `.' or `->' after a scalar type, most likely the
-	 program is trying to get a member of a non-aggregate
-	 type.  */
-      if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE)
-	  || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_COMPL)
-	{
-	  cp_parser_error (parser, "request for member of non-aggregate type");
-	  return;
-	}
-
       /* Look for the `::' token.  */
       cp_parser_require (parser, CPP_SCOPE, "`::'");
     }
--- 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;
--- gcc/testsuite/g++.dg/template/member8.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/member8.C	(revision 132298)
@@ -0,0 +1,25 @@
+// PR c++/35138
+// { dg-do compile }
+
+namespace N1 { struct A { }; }
+namespace N2 { struct A { }; }
+using namespace N1;
+using namespace N2;
+
+template <typename T> int
+foo (T const &t)
+{
+  return t.A;
+}
+
+struct B
+{
+  int A;
+};
+
+int
+main ()
+{
+  B b;
+  foo (b);
+}