On 5/4/20 9:51 PM, Marek Polacek wrote:
On Mon, May 04, 2020 at 05:41:37PM -0400, Jason Merrill via Gcc-patches wrote:
On 5/4/20 4:37 PM, Marek Polacek wrote:
On Fri, May 01, 2020 at 04:12:35PM -0400, Jason Merrill wrote:
@@ -7754,9 +7755,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser 
*parser,
        }
      if (dependent_p)
-    /* Tell cp_parser_lookup_name that there was an object, even though it's
-       type-dependent.  */
-    parser->context->object_type = unknown_type_node;
+    {
+      /* If we don't have a (type-dependent) object of class type, use
+        decltype to signal that there was an object.  */
+      if (type == NULL_TREE)
+       {
+         type = finish_decltype_type (postfix_expression,
+                                      /*member_access_p=*/true,

This should be false, we don't want the special decltype semantics for a
member-access expression.

Fixed.

+                                      tf_warning_or_error);
+         /* For -> this decltype will produce T*, but we want T.  */
+         if (token_type == CPP_DEREF)
+           type = build_min_nt_loc (start_loc, INDIRECT_REF, type);

Don't we want the INDIRECT_REF inside the decltype?  How does it work like
this?

I'm now not quite sure what I perpetrated there; I must've messed it up when I 
was
looking at what we do with it in the debugger.  I assume it worked by accident.

I've moved the INDIRECT_REF inside the decltype, but I had to use the original
expression

Hmm, I would expect the type of the ARROW_EXPR to be what we want without
messing with INDIRECT_REF separately.

Weirdly decltype/typeof of the ARROW_EXPR for e.g. bar((T)1)->template M<T>::fn 
()
from the lookup15.C test still gives me M<T> *.

In general, if something seems weird, please investigate more before working around it.

In this case I can't reproduce the weirdness; your new tests all still pass for me with the patch below:

Jason
commit 042929a2220ff6e2f54c23cd27f360fc285363e3
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon May 4 22:57:55 2020 -0400

    simpler

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 90fc9304ef2..5832025443d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7694,7 +7694,6 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
   bool pseudo_destructor_p;
   tree scope = NULL_TREE;
   location_t start_loc = postfix_expression.get_start ();
-  tree orig_expr = postfix_expression;
 
   /* If this is a `->' operator, dereference the pointer.  */
   if (token_type == CPP_DEREF)
@@ -7756,20 +7755,11 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
 
   if (dependent_p)
     {
-      tree type = TREE_TYPE (orig_expr);
+      tree type = TREE_TYPE (postfix_expression);
       /* If we don't have a (type-dependent) object of class type, use
-	 typeof to figure out the type of the object.  Use the original
-	 expression -- typeof on an ARROW_EXPR may not give the desirable
-	 result.  */
+	 typeof to figure out the type of the object.  */
       if (type == NULL_TREE)
-	{
-	  /* For -> this typeof will produce T*, but we want T.  */
-	  if (token_type == CPP_DEREF)
-	    orig_expr = build_min_nt_loc (start_loc, INDIRECT_REF, orig_expr);
-	  type = finish_typeof (orig_expr);
-	}
-      else if (token_type == CPP_DEREF && POINTER_TYPE_P (type))
-	type = TREE_TYPE (type);
+	type = finish_typeof (postfix_expression);
       parser->context->object_type = type;
     }
 

Reply via email to