summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cxx-pretty-print.c4
-rw-r--r--gcc/cp/error.c8
-rw-r--r--gcc/cp/init.c11
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/cp/typeck.c18
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent10.C22
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent7.C22
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent8.C21
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent9.C22
11 files changed, 144 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0108c295494..29ef50d6fde 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index ff377d36fc7..1c84e161f5d 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -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:
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 6d579630400..6fa99a7a801 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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:
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0fa2365e585..926dfcd9c89 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3d61c98a5e9..59eb9c742d4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 651067adb9b..21e7fe4a4ee 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 74b8cffb12f..d9d4e545e85 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..0adac25f08d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent10.C
@@ -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
index 00000000000..ee34327ad63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent7.C
@@ -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
index 00000000000..369e137317c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent8.C
@@ -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
index 00000000000..c046312d558
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent9.C
@@ -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;
+};
OpenPOWER on IntegriCloud