diff mbox

[C++] PR 57543

Message ID 53861796.7070309@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 28, 2014, 5:06 p.m. UTC
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.

///////////////////////

Comments

Jason Merrill May 29, 2014, 1:34 p.m. UTC | #1
On 05/28/2014 01:06 PM, Paolo Carlini wrote:
> Now, I got this "insane" idea: would it make sense to simply invert the
> substitutions (args and return) unconditionally?

If we're going to change the order, I want to do it in a more correct, 
rather than differently wrong, way.  DR 1227 clarified that substitution 
should proceed in lexical order.

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1227

Jason
Paolo Carlini May 29, 2014, 1:49 p.m. UTC | #2
Hi,

On 05/29/2014 03:34 PM, Jason Merrill wrote:
> On 05/28/2014 01:06 PM, Paolo Carlini wrote:
>> Now, I got this "insane" idea: would it make sense to simply invert the
>> substitutions (args and return) unconditionally?
>
> If we're going to change the order, I want to do it in a more correct, 
> rather than differently wrong, way.  DR 1227 clarified that 
> substitution should proceed in lexical order.
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1227
Ok, I had no idea we had this kind of much more general issue. Then this 
is really something for you to handle ;)

Thanks!
Paolo.
diff mbox

Patch

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);
 }