From 6c74ff23008028116fa0ee942d2905e56a55fbab Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 26 Mar 2013 23:01:41 -0400 Subject: [PATCH] re PR c++/52597 ([C++11] confusing diagnostics for invalid use of non-static member function in decltype) PR c++/52597 * typeck.c (invalid_nonstatic_memfn_p): Use get_first_fn. Take tree. * semantics.c (finish_decltype_type): Check it before type_unknown_p. * cp-tree.h: Adjust prototype. From-SVN: r197131 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/semantics.c | 6 +++--- gcc/cp/typeck.c | 11 +++++++++-- gcc/testsuite/g++.dg/cpp0x/decltype50.C | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/template/overload6.C | 5 ++--- gcc/testsuite/g++.dg/template/ptrmem4.C | 4 ++-- gcc/testsuite/g++.old-deja/g++.mike/p11110.C | 5 ++--- 8 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype50.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0c5bcee6ebe..3fe07d9711b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2013-03-26 Jason Merrill + PR c++/52597 + * typeck.c (invalid_nonstatic_memfn_p): Use get_first_fn. Take tree. + * semantics.c (finish_decltype_type): Check it before type_unknown_p. + * cp-tree.h: Adjust prototype. + PR c++/45282 * typeck2.c (build_m_component_ref): Handle prvalue object. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 401868549cd..36671d5c3a3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5988,7 +5988,7 @@ extern tree build_typed_address (tree, tree); extern tree build_nop (tree, tree); extern tree non_reference (tree); extern tree lookup_anon_field (tree, tree); -extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t); +extern bool invalid_nonstatic_memfn_p (tree, tsubst_flags_t); extern tree convert_member_func_to_ptr (tree, tree, tsubst_flags_t); extern tree convert_ptrmem (tree, tree, bool, bool, tsubst_flags_t); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 333980e88e7..e8fc778dd2e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5275,6 +5275,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, expr = resolve_nondeduced_context (expr); + if (invalid_nonstatic_memfn_p (expr, complain)) + return error_mark_node; + if (type_unknown_p (expr)) { if (complain & tf_error) @@ -5282,9 +5285,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, return error_mark_node; } - if (invalid_nonstatic_memfn_p (expr, complain)) - return error_mark_node; - /* To get the size of a static data member declared as an array of unknown bound, we need to instantiate it. */ if (TREE_CODE (expr) == VAR_DECL diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4e42a9d3d7b..8778b2cf7b9 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1766,9 +1766,16 @@ cxx_alignas_expr (tree e) violates these rules. */ bool -invalid_nonstatic_memfn_p (const_tree expr, tsubst_flags_t complain) +invalid_nonstatic_memfn_p (tree expr, tsubst_flags_t complain) { - if (expr && DECL_NONSTATIC_MEMBER_FUNCTION_P (expr)) + if (expr == NULL_TREE) + return false; + /* Don't enforce this in MS mode. */ + if (flag_ms_extensions) + return false; + if (is_overloaded_fn (expr) && !really_overloaded_fn (expr)) + expr = get_first_fn (expr); + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr)) { if (complain & tf_error) error ("invalid use of non-static member function"); diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype50.C b/gcc/testsuite/g++.dg/cpp0x/decltype50.C new file mode 100644 index 00000000000..dc3332ac525 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype50.C @@ -0,0 +1,18 @@ +// PR c++/52597 +// { dg-require-effective-target c++11 } + +struct A { + int zip(); + + decltype(zip) bar0; // { dg-error "invalid use of non-static member function" } + void bar1() { + typedef decltype(this->A::zip) x; // { dg-error "invalid use of non-static member function" } + } + void bar2() { + typedef decltype(A::zip) x; // { dg-error "invalid use of non-static member function" } + } +}; + +typedef decltype(A().zip) x; // { dg-error "invalid use of non-static member function" } + +// { dg-prune-output "invalid type in declaration" } diff --git a/gcc/testsuite/g++.dg/template/overload6.C b/gcc/testsuite/g++.dg/template/overload6.C index 5e26c448b18..8d574e73087 100644 --- a/gcc/testsuite/g++.dg/template/overload6.C +++ b/gcc/testsuite/g++.dg/template/overload6.C @@ -4,7 +4,7 @@ // PR 21592:ICE // Origin: Volker Reichelt -template void unique(T,T); // { dg-message "note" } +template void unique(T,T); struct A { @@ -13,6 +13,5 @@ struct A template void foo() { - unique(A().begin); // { dg-error "no matching function" "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 16 } + unique(A().begin); // { dg-error "invalid use of non-static member function" } } diff --git a/gcc/testsuite/g++.dg/template/ptrmem4.C b/gcc/testsuite/g++.dg/template/ptrmem4.C index 14f36d4e386..076503202c0 100644 --- a/gcc/testsuite/g++.dg/template/ptrmem4.C +++ b/gcc/testsuite/g++.dg/template/ptrmem4.C @@ -6,7 +6,7 @@ // Pointer to member function template argument deduction ICE. -template void queryAliases(CONT& fill_me); // { dg-message "queryAliases|no known conversion" } +template void queryAliases(CONT& fill_me); struct SpyExample { @@ -16,5 +16,5 @@ struct SpyExample void SpyExample::ready() { - queryAliases(inputs); // { dg-error "matching|unresolved" } + queryAliases(inputs); // { dg-error "invalid" } } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p11110.C b/gcc/testsuite/g++.old-deja/g++.mike/p11110.C index 7e3a1ffa335..714f628f5ef 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p11110.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p11110.C @@ -6,7 +6,7 @@ class data; class conatiner { public: virtual void* first (); - virtual data* contents (void* i); // { dg-message "conatiner::contents|no known conversion" } + virtual data* contents (void* i); }; class user { @@ -17,6 +17,5 @@ private: }; data* user::data1() const { - return (_c.contents (_c.first)); // { dg-error "match" } - // { dg-message "candidate" "candidate note" { target *-*-* } 20 } + return (_c.contents (_c.first)); // { dg-error "invalid use of non-static member function" } } -- 2.30.2