From 26d880e6480291217e03622c7423dda93b172497 Mon Sep 17 00:00:00 2001 From: nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 18 Jul 2003 17:19:41 +0000 Subject: [PATCH] cp: * cp-tree.h (finish_non_static_data_member): Add object param. * method.c (hack_identifier): Adjust. * pt.c (tsubst_copy_and_build) <COMPONENT_REF case>: Don't search again for a FIELD_DECL. * semantics.c (finish_non_static_data_member): Add object parameter. Always save the DECL in the COMPONENT_REF. * call.c (resolve_scoped_fn_name): Adjust. testsuite: * g++.dg/parse/non-dependent2.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69564 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/call.c | 2 +- gcc/cp/cp-tree.h | 2 +- gcc/cp/method.c | 2 +- gcc/cp/pt.c | 2 + gcc/cp/semantics.c | 50 ++++++++++++++------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.dg/parse/non-dependent2.C | 37 +++++++++++++++ 7 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/non-dependent2.C diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a9323cc1f91d..6f677a5243b2 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2651,7 +2651,7 @@ resolve_scoped_fn_name (tree scope, tree name) /* It might be the name of a function pointer member. */ if (fn && TREE_CODE (fn) == FIELD_DECL) - fn = finish_non_static_data_member (fn, scope); + fn = finish_non_static_data_member (fn, current_class_ref, scope); } if (!fn) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1728b3793535..4f2a1432e466 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4129,7 +4129,7 @@ extern tree finish_label_stmt (tree); extern void finish_label_decl (tree); extern void finish_subobject (tree); extern tree finish_parenthesized_expr (tree); -extern tree finish_non_static_data_member (tree, tree); +extern tree finish_non_static_data_member (tree, tree, tree); extern tree begin_stmt_expr (void); extern tree finish_stmt_expr (tree); extern tree perform_koenig_lookup (tree, tree); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index e1ffaad3769a..fdc026b3476f 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -117,7 +117,7 @@ hack_identifier (tree value, tree name) type = TREE_TYPE (value); if (TREE_CODE (value) == FIELD_DECL) - value = finish_non_static_data_member (value, + value = finish_non_static_data_member (value, current_class_ref, /*qualifying_scope=*/NULL_TREE); else if ((TREE_CODE (value) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (value)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bbce47e769ae..9d66c3c0addb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8273,6 +8273,8 @@ tsubst_copy_and_build (tree t, return error_mark_node; } } + else if (TREE_CODE (member) == FIELD_DECL) + return finish_non_static_data_member (member, object, NULL_TREE); return finish_class_member_access_expr (object, member); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 3d704ebe1942..812ef6df2dc1 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1218,11 +1218,11 @@ finish_parenthesized_expr (tree expr) preceded by `.' or `->'. */ tree -finish_non_static_data_member (tree decl, tree qualifying_scope) +finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) { my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909); - if (current_class_ptr == NULL_TREE) + if (!object) { if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) @@ -1236,27 +1236,42 @@ finish_non_static_data_member (tree decl, tree qualifying_scope) } TREE_USED (current_class_ptr) = 1; if (processing_template_decl) - return build_min (COMPONENT_REF, TREE_TYPE (decl), - current_class_ref, DECL_NAME (decl)); - else { - tree access_type = current_class_type; - tree object = current_class_ref; + tree type = TREE_TYPE (decl); - while (access_type - && !DERIVED_FROM_P (context_for_name_lookup (decl), access_type)) + if (TREE_CODE (type) == REFERENCE_TYPE) + type = TREE_TYPE (type); + else + { + /* Set the cv qualifiers */ + int quals = cp_type_quals (TREE_TYPE (current_class_ref)); + + if (DECL_MUTABLE_P (decl)) + quals &= ~TYPE_QUAL_CONST; + + quals |= cp_type_quals (TREE_TYPE (decl)); + type = cp_build_qualified_type (type, quals); + } + + return build_min (COMPONENT_REF, type, object, decl); + } + else + { + tree access_type = TREE_TYPE (object); + tree lookup_context = context_for_name_lookup (decl); + + while (!DERIVED_FROM_P (lookup_context, access_type)) { access_type = TYPE_CONTEXT (access_type); while (access_type && DECL_P (access_type)) access_type = DECL_CONTEXT (access_type); - } - if (!access_type) - { - cp_error_at ("object missing in reference to `%D'", - decl); - error ("from this location"); - return error_mark_node; + if (!access_type) + { + cp_error_at ("object missing in reference to `%D'", decl); + error ("from this location"); + return error_mark_node; + } } perform_or_defer_access_check (TYPE_BINFO (access_type), decl); @@ -1357,7 +1372,8 @@ finish_qualified_id_expr (tree qualifying_class, tree expr, bool done, } if (TREE_CODE (expr) == FIELD_DECL) - expr = finish_non_static_data_member (expr, qualifying_class); + expr = finish_non_static_data_member (expr, current_class_ref, + qualifying_class); else if (BASELINK_P (expr) && !processing_template_decl) { tree fn; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 60a68bb9b01f..4a3fcb97aca1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-07-18 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/parse/non-dependent2.C: New test. + 2003-07-18 Andrew Pinski <pinskia@physics.uc.edu> * g++.dg/init/init-ref4.C: xfail on targets without diff --git a/gcc/testsuite/g++.dg/parse/non-dependent2.C b/gcc/testsuite/g++.dg/parse/non-dependent2.C new file mode 100644 index 000000000000..46335c56bcce --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/non-dependent2.C @@ -0,0 +1,37 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 16 Jul 2003 <nathan@codesourcery.com> + +// A non-dependent field_decl can bind at parse time. + +template <class T> +struct Foo { + int j; // we never see this one. + int k; // { dg-error "" "" } + +}; + +struct Baz +{ + int j; + int k; // { dg-error "" "" } + +}; + +template <class T> +struct Bar : public Foo<T>, Baz { + + int baz () { return j; } // binds to Baz::j + int foo () { return this->k; } // { dg-error "request for member" "" } +}; + +int main() +{ + Bar<int> bar; + + bar.baz (); + bar.foo (); + + return 0; +} -- GitLab