public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4795] c++: non-static memfn call dependence cleanup [PR106086]
@ 2023-10-20 14:50 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2023-10-20 14:50 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:909672f02ff75a6a94c88dee4aa41e92edb1d1ed

commit r14-4795-g909672f02ff75a6a94c88dee4aa41e92edb1d1ed
Author: Patrick Palka <ppalka@redhat.com>
Date:   Fri Oct 20 10:50:19 2023 -0400

    c++: non-static memfn call dependence cleanup [PR106086]
    
    In cp_parser_postfix_expression, and in the CALL_EXPR case of
    tsubst_copy_and_build, we essentially repeat the type-dependent and
    COMPONENT_REF callee cases of finish_call_expr.  This patch deduplicates
    this logic by making both spots consistently go through finish_call_expr.
    
    This allows us to easily fix PR106086 -- which is about us neglecting to
    capture 'this' when we resolve a use of a non-static member function of
    the current instantiation only at lambda regeneration time -- by moving
    the call to maybe_generic_this_capture from the parser to finish_call_expr
    so that we consider capturing 'this' at regeneration time as well.
    
            PR c++/106086
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_postfix_expression): Consolidate three
            calls to finish_call_expr, one to build_new_method_call and
            one to build_min_nt_call_vec into one call to finish_call_expr.
            Don't call maybe_generic_this_capture here.
            * pt.cc (tsubst_copy_and_build) <case CALL_EXPR>: Remove
            COMPONENT_REF callee handling.
            (type_dependent_expression_p): Use t_d_object_e_p instead of
            t_d_e_p for COMPONENT_REF and OFFSET_REF.
            * semantics.cc (finish_call_expr): In the type-dependent case,
            call maybe_generic_this_capture here instead.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/crash127.C: Expect additional error due to
            being able to check the member access expression ahead of time.
            Strengthen the test by not instantiating the class template.
            * g++.dg/cpp1y/lambda-generic-this5.C: New test.

Diff:
---
 gcc/cp/parser.cc                                  | 52 +++--------------------
 gcc/cp/pt.cc                                      | 27 +-----------
 gcc/cp/semantics.cc                               | 12 ++++--
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C | 22 ++++++++++
 gcc/testsuite/g++.dg/template/crash127.C          |  3 +-
 5 files changed, 38 insertions(+), 78 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index c77e93ef104f..5483121f51c1 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -8055,54 +8055,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 					    close_paren_loc);
 	    iloc_sentinel ils (combined_loc);
 
-	    if (TREE_CODE (postfix_expression) == COMPONENT_REF)
-	      {
-		tree instance = TREE_OPERAND (postfix_expression, 0);
-		tree fn = TREE_OPERAND (postfix_expression, 1);
-
-		if (processing_template_decl
-		    && (type_dependent_object_expression_p (instance)
-			|| (!BASELINK_P (fn)
-			    && TREE_CODE (fn) != FIELD_DECL)
-			|| type_dependent_expression_p (fn)
-			|| any_type_dependent_arguments_p (args)))
-		  {
-		    maybe_generic_this_capture (instance, fn);
-		    postfix_expression
-		      = build_min_nt_call_vec (postfix_expression, args);
-		  }
-		else if (BASELINK_P (fn))
-		  {
-		  postfix_expression
-		    = (build_new_method_call
-		       (instance, fn, &args, NULL_TREE,
-			(idk == CP_ID_KIND_QUALIFIED
-			 ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
-			 : LOOKUP_NORMAL),
-			/*fn_p=*/NULL,
-			complain));
-		  }
-		else
-		  postfix_expression
-		    = finish_call_expr (postfix_expression, &args,
-					/*disallow_virtual=*/false,
-					/*koenig_p=*/false,
-					complain);
-	      }
-	    else if (TREE_CODE (postfix_expression) == OFFSET_REF
-		     || TREE_CODE (postfix_expression) == MEMBER_REF
-		     || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
+	    if (TREE_CODE (postfix_expression) == OFFSET_REF
+		|| TREE_CODE (postfix_expression) == MEMBER_REF
+		|| TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
 	      postfix_expression = (build_offset_ref_call_from_tree
 				    (postfix_expression, &args,
 				     complain));
-	    else if (idk == CP_ID_KIND_QUALIFIED)
-	      /* A call to a static class member, or a namespace-scope
-		 function.  */
-	      postfix_expression
-		= finish_call_expr (postfix_expression, &args,
-				    /*disallow_virtual=*/true,
-				    koenig_p,
-				    complain);
 	    else
 	      /* All other function calls.  */
 	      {
@@ -8115,12 +8073,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 				   "not permitted in intervening code");
 		    parser->omp_for_parse_state->fail = true;
 		  }
+		bool disallow_virtual = (idk == CP_ID_KIND_QUALIFIED);
 		postfix_expression
 		  = finish_call_expr (postfix_expression, &args,
-				      /*disallow_virtual=*/false,
+				      disallow_virtual,
 				      koenig_p,
 				      complain);
 	      }
+
 	    if (close_paren_loc != UNKNOWN_LOCATION)
 	      postfix_expression.set_location (combined_loc);
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index d2756c3ffb3a..bd84054ae12d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21364,31 +21364,6 @@ tsubst_copy_and_build (tree t,
 		 || TREE_CODE (function) == MEMBER_REF)
 	  ret = build_offset_ref_call_from_tree (function, &call_args,
 						 complain);
-	else if (TREE_CODE (function) == COMPONENT_REF)
-	  {
-	    tree instance = TREE_OPERAND (function, 0);
-	    tree fn = TREE_OPERAND (function, 1);
-
-	    if (processing_template_decl
-		&& (type_dependent_expression_p (instance)
-		    || (!BASELINK_P (fn)
-			&& TREE_CODE (fn) != FIELD_DECL)
-		    || type_dependent_expression_p (fn)
-		    || any_type_dependent_arguments_p (call_args)))
-	      ret = build_min_nt_call_vec (function, call_args);
-	    else if (!BASELINK_P (fn))
-	      ret = finish_call_expr (function, &call_args,
-				       /*disallow_virtual=*/false,
-				       /*koenig_p=*/false,
-				       complain);
-	    else
-	      ret = (build_new_method_call
-		      (instance, fn,
-		       &call_args, NULL_TREE,
-		       qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
-		       /*fn_p=*/NULL,
-		       complain));
-	  }
 	else if (concept_check_p (function))
 	  {
 	    /* FUNCTION is a template-id referring to a concept definition.  */
@@ -28585,7 +28560,7 @@ type_dependent_expression_p (tree expression)
       if (TREE_CODE (expression) == COMPONENT_REF
 	  || TREE_CODE (expression) == OFFSET_REF)
 	{
-	  if (type_dependent_expression_p (TREE_OPERAND (expression, 0)))
+	  if (type_dependent_object_expression_p (TREE_OPERAND (expression, 0)))
 	    return true;
 	  expression = TREE_OPERAND (expression, 1);
 	  if (identifier_p (expression))
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 5ccfa14b9b05..dc3c11461fbc 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -2793,18 +2793,19 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 	     (c++/89780, c++/107363).  This also suppresses the
 	     -Wredundant-move warning.  */
 	  suppress_warning (result, OPT_Wpessimizing_move);
-	  if (is_overloaded_fn (fn))
-	    fn = get_fns (fn);
 
 	  if (cfun)
 	    {
 	      bool abnormal = true;
-	      for (lkp_iterator iter (fn); abnormal && iter; ++iter)
+	      for (lkp_iterator iter (maybe_get_fns (fn)); iter; ++iter)
 		{
 		  tree fndecl = STRIP_TEMPLATE (*iter);
 		  if (TREE_CODE (fndecl) != FUNCTION_DECL
 		      || !TREE_THIS_VOLATILE (fndecl))
-		    abnormal = false;
+		    {
+		      abnormal = false;
+		      break;
+		    }
 		}
 	      /* FIXME: Stop warning about falling off end of non-void
 		 function.   But this is wrong.  Even if we only see
@@ -2814,6 +2815,9 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
 	      if (abnormal)
 		current_function_returns_abnormally = 1;
 	    }
+	  if (TREE_CODE (fn) == COMPONENT_REF)
+	    maybe_generic_this_capture (TREE_OPERAND (fn, 0),
+					TREE_OPERAND (fn, 1));
 	  return result;
 	}
       orig_args = make_tree_vector_copy (*args);
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C
new file mode 100644
index 000000000000..42f917094d9e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C
@@ -0,0 +1,22 @@
+// PR c++/106086
+// { dg-do compile { target c++14 } }
+
+template<class T>
+struct A {
+  void f(int) const;
+  static void g(int);
+};
+
+template<class T>
+struct B : A<T> {
+  auto f() const {
+    auto l1 = [&](auto x) { A<T>::f(x); };
+    auto l2 = [&](auto x) { A<T>::g(x); };
+    static_assert(sizeof(l1) == sizeof(this), "");
+    static_assert(sizeof(l2) == 1, "");
+    l1(0);
+    l2(0);
+  }
+};
+
+template struct B<void>;
diff --git a/gcc/testsuite/g++.dg/template/crash127.C b/gcc/testsuite/g++.dg/template/crash127.C
index b7c03251f8c6..fcf72d871db6 100644
--- a/gcc/testsuite/g++.dg/template/crash127.C
+++ b/gcc/testsuite/g++.dg/template/crash127.C
@@ -16,7 +16,6 @@ struct C : public A
   {
     B < &A::A > b;  // { dg-error "taking address of constructor 'A::A" "" { target c++98_only } }
     // { dg-error "taking address of constructor 'constexpr A::A" "" { target c++11 } .-1 }
+    // { dg-error "template argument 1 is invalid" "" { target *-*-* } .-2 }
   }
 };
-
-template class C < int >;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-10-20 14:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-20 14:50 [gcc r14-4795] c++: non-static memfn call dependence cleanup [PR106086] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).