This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to rework fixes for 38030, 38850, 39070


While I was looking at some mangling issues, the hackiness of my earlier fixes for these issues was bothering me. This approach reworks things so that KOENIG_LOOKUP_P indicates whether or not arg-dependent lookup is ever done for this call, so it doesn't change in a partial instantiation. This will also be relevant for mangling. I don't have a test case that changes with this, but this approach seems less likely to break.

Tested x86_64-pc-linux-gnu, applied to trunk and 4.4. I'll also test and apply to 4.3, since my earlier patches went there too.
2009-03-30  Jason Merrill  <jason@redhat.com>

	PR c++/38030, 38850, 39070
	* pt.c (type_dependent_expression_p_push): New fn.
	(tsubst_copy_and_build) [CALL_EXPR]: Only do arg-dep lookup when the
	substitution makes the call non-dependent.  Preserve koenig_p.
	* parser.c (cp_parser_postfix_expression): Only do arg-dep lookup
	for non-dependent calls.
	* semantics.c (finish_call_expr): Revert earlier changes.
	* cp-tree.h: Revert change to finish_call_expr prototype.

Index: cp/pt.c
===================================================================
*** cp/pt.c	(revision 145291)
--- cp/pt.c	(working copy)
*************** tsubst_copy_and_build (tree t,
*** 11450,11456 ****
  		    not appropriate, even if an unqualified-name was used
  		    to denote the function.  */
  		 && !DECL_FUNCTION_MEMBER_P (get_first_fn (function)))
! 		|| TREE_CODE (function) == IDENTIFIER_NODE))
  	  function = perform_koenig_lookup (function, call_args);
  
  	if (TREE_CODE (function) == IDENTIFIER_NODE)
--- 11450,11460 ----
  		    not appropriate, even if an unqualified-name was used
  		    to denote the function.  */
  		 && !DECL_FUNCTION_MEMBER_P (get_first_fn (function)))
! 		|| TREE_CODE (function) == IDENTIFIER_NODE)
! 	    /* Only do this when substitution turns a dependent call
! 	       into a non-dependent call.  */
! 	    && type_dependent_expression_p_push (t)
! 	    && !any_type_dependent_arguments_p (call_args))
  	  function = perform_koenig_lookup (function, call_args);
  
  	if (TREE_CODE (function) == IDENTIFIER_NODE)
*************** tsubst_copy_and_build (tree t,
*** 11481,11492 ****
  		       /*fn_p=*/NULL,
  		       complain));
  	  }
- 	/* Pass -1 for koenig_p so that build_new_function_call will
- 	   allow hidden friends found by arg-dependent lookup at template
- 	   parsing time.  */
  	return finish_call_expr (function, call_args,
  				 /*disallow_virtual=*/qualified_p,
! 				 /*koenig_p*/-1,
  				 complain);
        }
  
--- 11485,11493 ----
  		       /*fn_p=*/NULL,
  		       complain));
  	  }
  	return finish_call_expr (function, call_args,
  				 /*disallow_virtual=*/qualified_p,
! 				 koenig_p,
  				 complain);
        }
  
*************** type_dependent_expression_p (tree expres
*** 16454,16459 ****
--- 16455,16473 ----
    return (dependent_type_p (TREE_TYPE (expression)));
  }
  
+ /* Like type_dependent_expression_p, but it also works while not processing
+    a template definition, i.e. during substitution or mangling.  */
+ 
+ bool
+ type_dependent_expression_p_push (tree expr)
+ {
+   bool b;
+   ++processing_template_decl;
+   b = type_dependent_expression_p (expr);
+   --processing_template_decl;
+   return b;
+ }
+ 
  /* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call)
     contains a type-dependent expression.  */
  
Index: cp/semantics.c
===================================================================
*** cp/semantics.c	(revision 145291)
--- cp/semantics.c	(working copy)
*************** perform_koenig_lookup (tree fn, tree arg
*** 1836,1849 ****
     qualified.  For example a call to `X::f' never generates a virtual
     call.)
  
-    KOENIG_P is 1 if we want to perform argument-dependent lookup,
-    -1 if we don't, but we want to accept functions found by previous
-    argument-dependent lookup, and 0 if we want nothing to do with it.
- 
     Returns code for the call.  */
  
  tree
! finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p,
  		  tsubst_flags_t complain)
  {
    tree result;
--- 1836,1845 ----
     qualified.  For example a call to `X::f' never generates a virtual
     call.)
  
     Returns code for the call.  */
  
  tree
! finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
  		  tsubst_flags_t complain)
  {
    tree result;
*************** finish_call_expr (tree fn, tree args, bo
*** 1866,1872 ****
  	  || any_type_dependent_arguments_p (args))
  	{
  	  result = build_nt_call_list (fn, args);
! 	  KOENIG_LOOKUP_P (result) = koenig_p > 0;
  	  if (cfun)
  	    {
  	      do
--- 1862,1868 ----
  	  || any_type_dependent_arguments_p (args))
  	{
  	  result = build_nt_call_list (fn, args);
! 	  KOENIG_LOOKUP_P (result) = koenig_p;
  	  if (cfun)
  	    {
  	      do
*************** finish_call_expr (tree fn, tree args, bo
*** 1956,1962 ****
  
        if (!result)
  	/* A call to a namespace-scope function.  */
! 	result = build_new_function_call (fn, args, koenig_p != 0, complain);
      }
    else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
      {
--- 1952,1958 ----
  
        if (!result)
  	/* A call to a namespace-scope function.  */
! 	result = build_new_function_call (fn, args, koenig_p, complain);
      }
    else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
      {
*************** finish_call_expr (tree fn, tree args, bo
*** 1982,1990 ****
    if (processing_template_decl)
      {
        result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
!       /* Don't repeat arg-dependent lookup at instantiation time if this call
!          is not type-dependent.  */
!       KOENIG_LOOKUP_P (result) = 0;
      }
    return result;
  }
--- 1978,1984 ----
    if (processing_template_decl)
      {
        result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
!       KOENIG_LOOKUP_P (result) = koenig_p;
      }
    return result;
  }
Index: cp/parser.c
===================================================================
*** cp/parser.c	(revision 145291)
--- cp/parser.c	(working copy)
*************** cp_parser_postfix_expression (cp_parser 
*** 4738,4745 ****
  		    if (args)
  		      {
  			koenig_p = true;
! 			postfix_expression
! 			  = perform_koenig_lookup (postfix_expression, args);
  		      }
  		    else
  		      postfix_expression
--- 4738,4746 ----
  		    if (args)
  		      {
  			koenig_p = true;
! 			if (!any_type_dependent_arguments_p (args))
! 			  postfix_expression
! 			    = perform_koenig_lookup (postfix_expression, args);
  		      }
  		    else
  		      postfix_expression
*************** cp_parser_postfix_expression (cp_parser 
*** 4761,4768 ****
  		    if (!DECL_FUNCTION_MEMBER_P (fn))
  		      {
  			koenig_p = true;
! 			postfix_expression
! 			  = perform_koenig_lookup (postfix_expression, args);
  		      }
  		  }
  	      }
--- 4762,4770 ----
  		    if (!DECL_FUNCTION_MEMBER_P (fn))
  		      {
  			koenig_p = true;
! 			if (!any_type_dependent_arguments_p (args))
! 			  postfix_expression
! 			    = perform_koenig_lookup (postfix_expression, args);
  		      }
  		  }
  	      }
Index: cp/cp-tree.h
===================================================================
*** cp/cp-tree.h	(revision 145291)
--- cp/cp-tree.h	(working copy)
*************** extern bool dependent_template_p		(tree)
*** 4602,4607 ****
--- 4602,4608 ----
  extern bool dependent_template_id_p		(tree, tree);
  extern bool type_dependent_expression_p		(tree);
  extern bool any_type_dependent_arguments_p      (const_tree);
+ extern bool type_dependent_expression_p_push	(tree);
  extern bool value_dependent_expression_p	(tree);
  extern bool any_value_dependent_elements_p      (const_tree);
  extern bool dependent_omp_for_p			(tree, tree, tree, tree);
*************** extern tree finish_stmt_expr_expr		(tree
*** 4761,4767 ****
  extern tree finish_stmt_expr			(tree, bool);
  extern tree stmt_expr_value_expr		(tree);
  extern tree perform_koenig_lookup		(tree, tree);
! extern tree finish_call_expr			(tree, tree, bool, int, 
  						 tsubst_flags_t);
  extern tree finish_increment_expr		(tree, enum tree_code);
  extern tree finish_this_expr			(void);
--- 4762,4768 ----
  extern tree finish_stmt_expr			(tree, bool);
  extern tree stmt_expr_value_expr		(tree);
  extern tree perform_koenig_lookup		(tree, tree);
! extern tree finish_call_expr			(tree, tree, bool, bool, 
  						 tsubst_flags_t);
  extern tree finish_increment_expr		(tree, enum tree_code);
  extern tree finish_this_expr			(void);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]