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]

Re: [PATCH, RFA, C++] ICE on ill-formed template_fun(&mem_fun) within template function


On Mar 29, 2006, Alexandre Oliva <aoliva@redhat.com> wrote:

> This alternate, much simpler patch, appears to fix the problem in
> mainline, by extending the code that matches ADDR_EXPR and
> COMPONENT_REF to avoid wrapping them in a NON_DEPENDENT_EXPR if their
> inner_expr is an overloaded function, to match ADDR_EXPR of
> COMPONENT_REF as well.  I'm still testing it, but does it look
> like it might be a better fix for the problem?

FWIW, testing succeeded on amd64-linux-gnu.  I was set off track for a
while because of the various failures in the trunk that looked like
regressions possibly related with the patch, but that turned out to
also be present without it.

> Red Hat bugzilla #168260 triggered an ICE on an ill-formed construct,
> taking the address of a non-static member function using an
> unqualified id, within a template function, and passing that as an
> argument in a function call requiring overload resolution.  Fixing
> that uncovered a number of other situations in which we used to fail
> or to handle things differently within templates.

:ADDPATCH c++/template:

Red Hat bugzilla #168260 triggered an ICE on an ill-formed construct,
taking the address of a non-static member function using an
unqualified id, within a template function, and passing that as an
argument in a function call requiring overload resolution.  Fixing
that uncovered a number of other situations in which we used to fail
or to handle things differently within templates.

for gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* pt.c (build_non_dependent_expr): Leave ADDR_EXPR of
	COMPONENT_REF alone.

for gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* g++.dg/template/dependent-expr5.C: New test.

Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c.orig	2006-03-28 03:26:53.000000000 -0300
+++ gcc/cp/pt.c	2006-03-29 04:54:25.000000000 -0300
@@ -12894,10 +12894,11 @@ build_non_dependent_expr (tree expr)
     return expr;
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
-  inner_expr = (TREE_CODE (expr) == ADDR_EXPR ?
-		TREE_OPERAND (expr, 0) :
-		TREE_CODE (expr) == COMPONENT_REF ?
-		TREE_OPERAND (expr, 1) : expr);
+  inner_expr = expr;
+  if (TREE_CODE (inner_expr) == ADDR_EXPR)
+    inner_expr = TREE_OPERAND (inner_expr, 0);
+  if (TREE_CODE (inner_expr) == COMPONENT_REF)
+    inner_expr = TREE_OPERAND (inner_expr, 1);
   if (is_overloaded_fn (inner_expr)
       || TREE_CODE (inner_expr) == OFFSET_REF)
     return expr;
Index: gcc/testsuite/g++.dg/template/dependent-expr5.C
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/g++.dg/template/dependent-expr5.C	2006-03-29 04:29:34.000000000 -0300
@@ -0,0 +1,114 @@
+// { dg-do compile }
+
+// Copyright 2005 Free Software Foundation
+// contributed by Alexandre Oliva <aoliva@redhat.com>
+// inspired in the failure reported in Red Hat bugzilla #168260.
+
+template<class F> void bind(F f) {}
+
+template<class F> void bindm(F f) {}
+template<class F, class T> void bindm(F (T::*f)(void)) {} // { dg-error "note" }
+
+template<class F> void bindn(F f) {}
+template<class F, class T> void bindn(F (*f)(T)) {}
+
+template<class F> void bindb(F f) {}
+template<class F, class T> void bindb(F (*f)(T)) {} // { dg-error "note" }
+template<class F, class T> void bindb(F (T::*f)(void)) {} // { dg-error "note" }
+
+struct foo {
+  static int baist;
+  int bait;
+  void barf ();
+  static void barf (int);
+
+  struct bar {
+    static int baikst;
+    int baikt;
+    void bark ();
+    static void bark (int);
+
+    bar() {
+      bind (&baist);
+      bind (&foo::baist);
+      bind (&bait); // { dg-error "nonstatic data member" }
+      bind (&foo::bait);
+
+      bind (&baikst);
+      bind (&bar::baikst);
+      bind (&baikt); // ok, this->baikt
+      bind (&bar::baikt);
+
+      bind (&barf); // { dg-error "no matching function" }
+      bind (&foo::barf); // { dg-error "no matching function" }
+
+      bindm (&barf); // { dg-error "no matching function" }
+      bindm (&foo::barf);
+
+      bindn (&barf);
+      bindn (&foo::barf);
+
+      bindb (&barf);
+      bindb (&foo::barf); // { dg-error "ambiguous" }
+
+      bind (&bark); // { dg-error "no matching function" }
+      bind (&bar::bark); // { dg-error "no matching function" }
+
+      bindm (&bark); // { dg-error "no matching function" }
+      bindm (&bar::bark);
+
+      bindn (&bark);
+      bindn (&bar::bark);
+
+      bindb (&bark);
+      bindb (&bar::bark); // { dg-error "ambiguous" }
+    }
+  };
+
+  template <typename T>
+  struct barT {
+    static int baikst;
+    int baikt;
+    void bark ();
+    static void bark (int);
+
+    barT() {
+      bind (&baist);
+      bind (&foo::baist);
+      bind (&bait); // { dg-error "nonstatic data member" }
+      bind (&foo::bait);
+
+      bind (&baikst);
+      bind (&barT::baikst);
+      bind (&baikt); // ok, this->baikt
+      bind (&barT::baikt);
+
+      bind (&barf); // { dg-error "no matching function" }
+      bind (&foo::barf); // { dg-error "no matching function" }
+
+      bindm (&barf); // { dg-error "no matching function" }
+      bindm (&foo::barf);
+
+      bindn (&barf);
+      bindn (&foo::barf);
+
+      bindb (&barf);
+      bindb (&foo::barf); // { dg-error "ambiguous" }
+
+      bind (&bark); // { dg-error "no matching function" }
+      bind (&barT::bark); // { dg-error "no matching function" }
+
+      bindm (&bark); // { dg-error "no matching function" }
+      bindm (&barT::bark);
+
+      bindn (&bark);
+      bindn (&barT::bark);
+
+      bindb (&bark);
+      bindb (&barT::bark); // { dg-error "ambiguous" }
+    }
+  };
+
+  bar bard;
+  barT<void> bart;
+} bad;
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America        http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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