Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 203308)
+++ cp/parser.c	(working copy)
@@ -1857,7 +1857,7 @@ static tree cp_parser_nested_name_specifier
 static tree cp_parser_qualifying_entity
   (cp_parser *, bool, bool, bool, bool, bool);
 static tree cp_parser_postfix_expression
-  (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
+  (cp_parser *, bool, bool, bool, bool&, cp_id_kind *);
 static tree cp_parser_postfix_open_square_expression
   (cp_parser *, tree, bool, bool);
 static tree cp_parser_postfix_dot_deref_expression
@@ -5531,14 +5531,14 @@ cp_parser_qualifying_entity (cp_parser *parser,
    `&' operator.  CAST_P is true if this expression is the target of a
    cast.
 
-   If MEMBER_ACCESS_ONLY_P, we only allow postfix expressions that are
-   class member access expressions [expr.ref].
+   If IS_MEMBER_ACCESS is false, we are not returning a class member
+   access expression [expr.ref].
 
    Returns a representation of the expression.  */
 
 static tree
 cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
-                              bool member_access_only_p, bool decltype_p,
+                              bool decltype_p, bool& is_member_access,
 			      cp_id_kind * pidk_return)
 {
   cp_token *token;
@@ -5546,7 +5546,7 @@ cp_parser_postfix_expression (cp_parser *parser, b
   enum rid keyword;
   cp_id_kind idk = CP_ID_KIND_NONE;
   tree postfix_expression = NULL_TREE;
-  bool is_member_access = false;
+  is_member_access = false;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -6066,10 +6066,7 @@ cp_parser_postfix_expression (cp_parser *parser, b
 	default:
 	  if (pidk_return != NULL)
 	    * pidk_return = idk;
-          if (member_access_only_p)
-            return is_member_access? postfix_expression : error_mark_node;
-          else
-            return postfix_expression;
+	  return postfix_expression;
 	}
     }
 
@@ -7003,9 +7000,9 @@ cp_parser_unary_expression (cp_parser *parser, boo
       return expression;
     }
 
+  bool is_member_access;
   return cp_parser_postfix_expression (parser, address_p, cast_p,
-                                       /*member_access_only_p=*/false,
-				       decltype_p,
+				       decltype_p, is_member_access,
 				       pidk);
 }
 
@@ -11678,33 +11675,42 @@ cp_parser_decltype_expr (cp_parser *parser,
         id_expression_or_member_access_p = true;
     }
 
-  if (!id_expression_or_member_access_p)
+  if (id_expression_or_member_access_p)
     {
-      /* Abort the id-expression parse.  */
-      cp_parser_abort_tentative_parse (parser);
+      /* We have parsed an id-expression.  */
+      cp_parser_parse_definitely (parser);
+      return expr;
+    }
 
-      /* Parsing tentatively, again.  */
-      cp_parser_parse_tentatively (parser);
+  /* Abort the id-expression parse.  */
+  cp_parser_abort_tentative_parse (parser);
 
-      /* Parse a class member access.  */
-      expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
-                                           /*cast_p=*/false, /*decltype*/true,
-                                           /*member_access_only_p=*/true, NULL);
+  /* Parsing tentatively, again.  */
+  cp_parser_parse_tentatively (parser);
 
-      if (expr 
-          && expr != error_mark_node
-          && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
-        /* We have an id-expression.  */
-        id_expression_or_member_access_p = true;
-    }
+  /* Parse a postfix expression.  */
+  bool is_member_access;
+  expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
+				       /*cast_p=*/false,
+				       /*decltype_p*/true,
+				       is_member_access, NULL);
 
-  if (id_expression_or_member_access_p)
-    /* We have parsed the complete id-expression or member access.  */
+  bool postfix_expression_ok_p =
+    (expr && expr != error_mark_node
+     && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN);
+
+  if (postfix_expression_ok_p
+      && is_member_access)
+    id_expression_or_member_access_p = true;
+
+  if (postfix_expression_ok_p)
+    /* We have parsed a member access or a different kind of valid
+       postfix expression, eg, a pseudo destructor call [expr.pseudo]
+       (c++/58633).  */
     cp_parser_parse_definitely (parser);
   else
     {
-      /* Abort our attempt to parse an id-expression or member access
-         expression.  */
+      /* Abort our attempt to parse a postfix-expression.  */
       cp_parser_abort_tentative_parse (parser);
 
       /* Parse a full expression.  */
Index: testsuite/g++.dg/cpp0x/decltype57.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype57.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/decltype57.C	(working copy)
@@ -0,0 +1,8 @@
+// PR c++/58633
+// { dg-do compile { target c++11 } }
+
+void foo(int i)
+{
+  typedef int I;
+  decltype(i.I::~I())* p;
+}
