aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-03-26 23:01:41 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-03-26 23:01:41 -0400
commit6c74ff23008028116fa0ee942d2905e56a55fbab (patch)
tree2e50cb35e78c966ced31e42dc6a61b9320d90a4f
parent845367eb3b3a6845a603e2d959c85fba9ce921da (diff)
downloadgcc-6c74ff23008028116fa0ee942d2905e56a55fbab.zip
gcc-6c74ff23008028116fa0ee942d2905e56a55fbab.tar.gz
gcc-6c74ff23008028116fa0ee942d2905e56a55fbab.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/semantics.c6
-rw-r--r--gcc/cp/typeck.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype50.C18
-rw-r--r--gcc/testsuite/g++.dg/template/overload6.C5
-rw-r--r--gcc/testsuite/g++.dg/template/ptrmem4.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p11110.C5
8 files changed, 42 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0c5bcee..3fe07d9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2013-03-26 Jason Merrill <jason@redhat.com>
+ 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 4018685..36671d5 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 333980e8..e8fc778 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 4e42a9d..8778b2c 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 0000000..dc3332a
--- /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 5e26c44..8d574e7 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 <reichelt@gcc.gnu.org>
-template<typename T> void unique(T,T); // { dg-message "note" }
+template<typename T> void unique(T,T);
struct A
{
@@ -13,6 +13,5 @@ struct A
template<int> 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 14f36d4..0765032 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 <class CONT> void queryAliases(CONT& fill_me); // { dg-message "queryAliases|no known conversion" }
+template <class CONT> 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 7e3a1ff..714f628 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" }
}