re PR c++/13092 (Accepts invalid pointer-to-member conversion)
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Sun, 18 Jul 2004 12:37:57 +0000 (12:37 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Sun, 18 Jul 2004 12:37:57 +0000 (12:37 +0000)
PR c++/13092
* init.c (build_offset_ref): Build SCOPE_REF with non-null
TREE_TYPE for non-dependent names.
* typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF.
* pt.c (type_dependent_expression_p): Handle SCOPE_REF with
unknown_type_node as its TREE_TYPE.
* cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
* error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
(dump_expr) <SCOPE_REF case>: Likewise.

* g++.dg/template/non-dependent7.C: New test.
* g++.dg/template/non-dependent8.C: Likewise.
* g++.dg/template/non-dependent9.C: Likewise.
* g++.dg/template/non-dependent10.C: Likewise.

From-SVN: r84889

gcc/cp/ChangeLog
gcc/cp/cxx-pretty-print.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/non-dependent10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/non-dependent7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/non-dependent8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/non-dependent9.C [new file with mode: 0644]

index 0108c2954940d0b4b58dee9ab1a1938b25b2234d..29ef50d6fdef7a9ab9b8ebca306b026cea43a289 100644 (file)
@@ -1,3 +1,15 @@
+2004-07-18  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/13092
+       * init.c (build_offset_ref): Build SCOPE_REF with non-null
+       TREE_TYPE for non-dependent names.
+       * typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF.
+       * pt.c (type_dependent_expression_p): Handle SCOPE_REF with
+       unknown_type_node as its TREE_TYPE.
+       * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
+       * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
+       (dump_expr) <SCOPE_REF case>: Likewise.
+
 2004-07-17  Jason Merrill  <jason@redhat.com>
 
        PR c++/16115
index ff377d36fc765e1aae0ba13bd3a2919d1b3f0d5f..1c84e161f5dd48ec9678f53086b760c88e29422b 100644 (file)
@@ -180,6 +180,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
       pp_cxx_template_id (pp, t);
       break;
 
+    case BASELINK:
+      pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
+      break;
+
     case RECORD_TYPE:
     case UNION_TYPE:
     case ENUMERAL_TYPE:
index 6d57963040028b03fdf605375348df81710f17be..6fa99a7a80145e583df590d2e5274f64eafd5973 100644 (file)
@@ -764,9 +764,7 @@ dump_decl (tree t, int flags)
       break;
 
     case SCOPE_REF:
-      dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS);
-      pp_colon_colon (cxx_pp); 
-      dump_decl (TREE_OPERAND (t, 1), flags);
+      pp_expression (cxx_pp, t);
       break;
 
     case ARRAY_REF:
@@ -1708,9 +1706,7 @@ dump_expr (tree t, int flags)
       break;
 
     case SCOPE_REF:
-      dump_type (TREE_OPERAND (t, 0), flags);
-      pp_cxx_colon_colon (cxx_pp);
-      dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+      pp_expression (cxx_pp, t);
       break;
 
     case CAST_EXPR:
index 0fa2365e585455ae45877b9473d944c798874aa4..926dfcd9c890ea8e1ac8777458fa796a97f8f2c1 100644 (file)
@@ -1334,7 +1334,7 @@ build_offset_ref (tree type, tree name, bool address_p)
   if (TREE_CODE (name) == TEMPLATE_DECL)
     return name;
 
-  if (processing_template_decl || uses_template_parms (type))
+  if (dependent_type_p (type) || type_dependent_expression_p (name))
     return build_min_nt (SCOPE_REF, type, name);
 
   if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
@@ -1398,6 +1398,7 @@ build_offset_ref (tree type, tree name, bool address_p)
       return error_mark_node;
     }
 
+  /* Set up BASEBINFO for member lookup.  */
   decl = maybe_dummy_object (type, &basebinfo);
 
   if (BASELINK_P (name) || DECL_P (name))
@@ -1416,6 +1417,14 @@ build_offset_ref (tree type, tree name, bool address_p)
       return error_mark_node;
     }
 
+  if (processing_template_decl)
+    {
+      if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
+       return build_min (SCOPE_REF, TREE_TYPE (member), type, orig_name);
+      else
+       return build_min (SCOPE_REF, TREE_TYPE (member), type, name);
+    }
+
   if (TREE_CODE (member) == TYPE_DECL)
     {
       TREE_USED (member) = 1;
index 3d61c98a5e95b3e85c00ca372532aa6b7cdc1943..59eb9c742d400369d85bb51b9345c0d179e28e4e 100644 (file)
@@ -11866,6 +11866,9 @@ type_dependent_expression_p (tree expression)
          if (TREE_CODE (expression) == IDENTIFIER_NODE)
            return false;
        }
+      /* SCOPE_REF with non-null TREE_TYPE is always non-dependent.  */
+      if (TREE_CODE (expression) == SCOPE_REF)
+       return false;
       
       if (TREE_CODE (expression) == BASELINK)
        expression = BASELINK_FUNCTIONS (expression);
index 651067adb9bb886ccd2c2bf3a094e0a2fd51c1d9..21e7fe4a4ee49980fc5d0808d4d1245adb62d4de 100644 (file)
@@ -3530,6 +3530,24 @@ build_x_unary_op (enum tree_code code, tree xarg)
     {
       if (type_dependent_expression_p (xarg))
        return build_min_nt (code, xarg, NULL_TREE);
+
+      /* For non-dependent pointer-to-member, the SCOPE_REF will be
+        processed during template substitution.  Just compute the
+        right type here and build an ADDR_EXPR around it for
+        diagnostics.  */
+      if (code == ADDR_EXPR && TREE_CODE (xarg) == SCOPE_REF)
+       {
+         tree type;
+         if (TREE_TYPE (xarg) == unknown_type_node)
+           type = unknown_type_node;
+         else if (TREE_CODE (TREE_TYPE (xarg)) == FUNCTION_TYPE)
+           type = build_pointer_type (TREE_TYPE (xarg));
+         else
+           type = build_ptrmem_type (TREE_OPERAND (xarg, 0),
+                                     TREE_TYPE (xarg));
+         return build_min (code, type, xarg, NULL_TREE);
+       }
+
       xarg = build_non_dependent_expr (xarg);
     }
 
index 74b8cffb12f65aad81cc9071247aa1f4efe27118..d9d4e545e85c162b4e3a039ce07d6c692b40cb9d 100644 (file)
@@ -1,3 +1,11 @@
+2004-07-18  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/13092
+       * g++.dg/template/non-dependent7.C: New test.
+       * g++.dg/template/non-dependent8.C: Likewise.
+       * g++.dg/template/non-dependent9.C: Likewise.
+       * g++.dg/template/non-dependent10.C: Likewise.
+
 2004-07-17  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/16337
diff --git a/gcc/testsuite/g++.dg/template/non-dependent10.C b/gcc/testsuite/g++.dg/template/non-dependent10.C
new file mode 100644 (file)
index 0000000..0adac25
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do compile }
+
+// Origin: Giovanni Bajo <giovannibajo@libero.it>
+
+// Two-phase name lookup for address of member:
+// Detecting overloading function error during parsing
+
+struct S
+{
+  int f(char);
+  int f(int);
+};
+
+template<int (S::*p)()>
+struct X
+{};
+
+template <class T>
+struct Foo
+{
+  X<&S::f> x;  // { dg-error "convert|no type" }
+};
diff --git a/gcc/testsuite/g++.dg/template/non-dependent7.C b/gcc/testsuite/g++.dg/template/non-dependent7.C
new file mode 100644 (file)
index 0000000..ee34327
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do compile }
+
+// Origin: Giovanni Bajo <giovannibajo@libero.it>
+
+// PR c++/13092: ICE taking address of member which is non-dependent
+
+struct S
+{
+  int i;
+};
+
+template<int S::*p>
+struct X
+{};
+
+template <class T>
+struct Foo
+{
+  X<&S::i> x;
+};
+
+template struct Foo<void>;
diff --git a/gcc/testsuite/g++.dg/template/non-dependent8.C b/gcc/testsuite/g++.dg/template/non-dependent8.C
new file mode 100644 (file)
index 0000000..369e137
--- /dev/null
@@ -0,0 +1,21 @@
+// { dg-do compile }
+
+// Origin: Giovanni Bajo <giovannibajo@libero.it>
+
+// Two-phase name lookup for address of member:
+// Detecting error during parsing
+
+struct S
+{
+  char i;
+};
+
+template<int S::*p>
+struct X
+{};
+
+template <class T>
+struct Foo
+{
+  X<&S::i> x;  // { dg-error "convert|no type" }
+};
diff --git a/gcc/testsuite/g++.dg/template/non-dependent9.C b/gcc/testsuite/g++.dg/template/non-dependent9.C
new file mode 100644 (file)
index 0000000..c046312
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do compile }
+
+// Origin: Giovanni Bajo <giovannibajo@libero.it>
+
+// Two-phase name lookup for address of member:
+// Overloading function
+
+struct S
+{
+  int f();
+  int f(int);
+};
+
+template<int (S::*p)()>
+struct X
+{};
+
+template <class T>
+struct Foo
+{
+  X<&S::f> x;
+};