Hi,

On 05/28/2014 06:33 PM, Jason Merrill wrote:
On 05/28/2014 11:59 AM, Paolo Carlini wrote:
I see. Even not considering this issue, there are many regression if I
inject for all method types. I'm afraid the issue turns out to be much
more tricky than I hoped, I guess I'm going to unassign myself, for now,
and work on some other pending issues in my todo. You are of course more
than welcome to take it and include my additional tests in your work!

OK.  Please add a link to this thread in the PR, if you haven't already.
Now, I got this "insane" idea: would it make sense to simply invert the substitutions (args and return) unconditionally? I'm asking because the below appears to pass the testsuite modulo decltype28.C which we would end up accepting, but likewise do current clang, icc, and Solaris Studio!?! (In case I would have also to double check something weird I was seeing if the injection happens for all method types...)

Thanks!
Paolo.

///////////////////////
Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 211024)
+++ cp/pt.c     (working copy)
@@ -11322,8 +11322,32 @@ tsubst_function_type (tree t,
   /* The TYPE_CONTEXT is not used for function/method types.  */
   gcc_assert (TYPE_CONTEXT (t) == NULL_TREE);
 
+  /* Substitute the argument types.  */
+  arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
+                               complain, in_decl);
+  if (arg_types == error_mark_node)
+    return error_mark_node;
+
   /* Substitute the return type.  */
+  tree save_ccp = current_class_ptr;
+  tree save_ccr = current_class_ref;
+  bool do_inject = (TREE_CODE (t) == METHOD_TYPE
+                   && TREE_CODE (TREE_TYPE (t)) == DECLTYPE_TYPE);
+  if (do_inject)
+    {
+      /* DR 1207: 'this' is in scope in the trailing return type.  */
+      tree this_type = TREE_TYPE (TREE_VALUE (arg_types));
+      inject_this_parameter (this_type, cp_type_quals (this_type));
+    }
+
   return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+  if (do_inject)
+    {
+      current_class_ptr = save_ccp;
+      current_class_ref = save_ccr;
+    }
+
   if (return_type == error_mark_node)
     return error_mark_node;
   /* DR 486 clarifies that creation of a function type with an
@@ -11344,12 +11368,6 @@ tsubst_function_type (tree t,
   if (abstract_virtuals_error_sfinae (ACU_RETURN, return_type, complain))
     return error_mark_node;
 
-  /* Substitute the argument types.  */
-  arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
-                               complain, in_decl);
-  if (arg_types == error_mark_node)
-    return error_mark_node;
-
   /* Construct a new type node and return it.  */
   if (TREE_CODE (t) == FUNCTION_TYPE)
     {
Index: testsuite/g++.dg/cpp0x/decltype28.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype28.C (revision 211024)
+++ testsuite/g++.dg/cpp0x/decltype28.C (working copy)
@@ -8,9 +8,9 @@ template <class F, int N>
 void ft (F f, typename enable_if<N!=0, int>::type) {}
 
 template< class F, int N >
-decltype(ft<F, N-1> (F(), 0))  // { dg-error "depth" }
+decltype(ft<F, N-1> (F(), 0))
 ft (F f, typename enable_if<N==0, int>::type) {}
 
 int main() {
-  ft<struct a*, 2> (0, 0);     // { dg-message "from here" }
+  ft<struct a*, 2> (0, 0);
 }

Reply via email to