From 3601f00362e227160cae47efbb179a579f5a5f51 Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Sun, 18 Jul 2004 12:37:57 +0000 Subject: [PATCH] re PR c++/13092 (Accepts invalid pointer-to-member conversion) 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) : Use pp_expression. (dump_expr) : 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 | 12 ++++++++++ gcc/cp/cxx-pretty-print.c | 4 ++++ gcc/cp/error.c | 8 ++----- gcc/cp/init.c | 11 +++++++++- gcc/cp/pt.c | 3 +++ gcc/cp/typeck.c | 18 +++++++++++++++ gcc/testsuite/ChangeLog | 8 +++++++ .../g++.dg/template/non-dependent10.C | 22 +++++++++++++++++++ .../g++.dg/template/non-dependent7.C | 22 +++++++++++++++++++ .../g++.dg/template/non-dependent8.C | 21 ++++++++++++++++++ .../g++.dg/template/non-dependent9.C | 22 +++++++++++++++++++ 11 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/non-dependent10.C create mode 100644 gcc/testsuite/g++.dg/template/non-dependent7.C create mode 100644 gcc/testsuite/g++.dg/template/non-dependent8.C create mode 100644 gcc/testsuite/g++.dg/template/non-dependent9.C 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 + + 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) : Use pp_expression. + (dump_expr) : Likewise. + 2004-07-17 Jason Merrill 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 + + 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 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 + +// Two-phase name lookup for address of member: +// Detecting overloading function error during parsing + +struct S +{ + int f(char); + int f(int); +}; + +template +struct X +{}; + +template +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 + +// PR c++/13092: ICE taking address of member which is non-dependent + +struct S +{ + int i; +}; + +template +struct X +{}; + +template +struct Foo +{ + X<&S::i> x; +}; + +template struct Foo; 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 + +// Two-phase name lookup for address of member: +// Detecting error during parsing + +struct S +{ + char i; +}; + +template +struct X +{}; + +template +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 + +// Two-phase name lookup for address of member: +// Overloading function + +struct S +{ + int f(); + int f(int); +}; + +template +struct X +{}; + +template +struct Foo +{ + X<&S::f> x; +}; -- 2.30.2