pt.c (build_non_dependent_expr): Leave ADDR_EXPR of COMPONENT_REF alone.
authorAlexandre Oliva <aoliva@redhat.com>
Sun, 14 May 2006 20:37:56 +0000 (20:37 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sun, 14 May 2006 20:37:56 +0000 (20:37 +0000)
gcc/cp/ChangeLog:
* pt.c (build_non_dependent_expr): Leave ADDR_EXPR of
COMPONENT_REF alone.
gcc/testsuite/ChangeLog:
* g++.dg/template/dependent-expr5.C: New test.

From-SVN: r113765

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/dependent-expr5.C [new file with mode: 0644]

index 898c13fef06a7fea331be6c47abca4494b4936f9..0af68ec773d1a464604c61774f3bb32073f39190 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-14  Alexandre Oliva  <aoliva@redhat.com>
+
+       * pt.c (build_non_dependent_expr): Leave ADDR_EXPR of
+       COMPONENT_REF alone.
+
 2006-05-11  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/27547
index 4d34da477ddae1ada444b290a224ccfabc0166b0..c1530fb120ff985392f8cf65b96b26d3d0cbde48 100644 (file)
@@ -12903,10 +12903,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 030c182f4e24f03a29c30735d4de2dc459142a78..a2a2ae5edf4532691af1b4d825d76f1f6cd70071 100644 (file)
@@ -1,3 +1,7 @@
+2006-05-14  Alexandre Oliva  <aoliva@redhat.com>
+
+       * g++.dg/template/dependent-expr5.C: New test.
+
 2006-05-14  Roger Sayle  <roger@eyesopen.com>
 
        PR middle-end/26729
diff --git a/gcc/testsuite/g++.dg/template/dependent-expr5.C b/gcc/testsuite/g++.dg/template/dependent-expr5.C
new file mode 100644 (file)
index 0000000..023f433
--- /dev/null
@@ -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;