Commit 80f7a782 by Jason Merrill Committed by Jason Merrill

re PR c++/48665 (type of const member function)

	PR c++/48665
	* rtti.c (get_typeid): Diagnose qualified function type.
	* pt.c (tsubst) [POINTER_TYPE]: Likewise.

From-SVN: r198160
parent af580858
2013-04-22 Jason Merrill <jason@redhat.com> 2013-04-22 Jason Merrill <jason@redhat.com>
PR c++/48665
* rtti.c (get_typeid): Diagnose qualified function type.
* pt.c (tsubst) [POINTER_TYPE]: Likewise.
* error.c (dump_aggr_type): Fix lambda detection. * error.c (dump_aggr_type): Fix lambda detection.
(dump_simple_decl): Pretty-print capture field. (dump_simple_decl): Pretty-print capture field.
......
...@@ -11521,6 +11521,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -11521,6 +11521,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return error_mark_node; return error_mark_node;
} }
else if (TREE_CODE (type) == FUNCTION_TYPE
&& (type_memfn_quals (type) != TYPE_UNQUALIFIED
|| type_memfn_rqual (type) != REF_QUAL_NONE))
{
if (complain & tf_error)
{
if (code == POINTER_TYPE)
error ("forming pointer to qualified function type %qT",
type);
else
error ("forming reference to qualified function type %qT",
type);
}
return error_mark_node;
}
else if (code == POINTER_TYPE) else if (code == POINTER_TYPE)
{ {
r = build_pointer_type (type); r = build_pointer_type (type);
......
...@@ -477,6 +477,16 @@ get_typeid (tree type, tsubst_flags_t complain) ...@@ -477,6 +477,16 @@ get_typeid (tree type, tsubst_flags_t complain)
referenced type. */ referenced type. */
type = non_reference (type); type = non_reference (type);
/* This is not one of the uses of a qualified function type in 8.3.5. */
if (TREE_CODE (type) == FUNCTION_TYPE
&& (type_memfn_quals (type) != TYPE_UNQUALIFIED
|| type_memfn_rqual (type) != REF_QUAL_NONE))
{
if (complain & tf_error)
error ("typeid of qualified function type %qT", type);
return error_mark_node;
}
/* The top-level cv-qualifiers of the lvalue expression or the type-id /* The top-level cv-qualifiers of the lvalue expression or the type-id
that is the operand of typeid are always ignored. */ that is the operand of typeid are always ignored. */
type = TYPE_MAIN_VARIANT (type); type = TYPE_MAIN_VARIANT (type);
......
...@@ -68,7 +68,7 @@ static_assert(sizeof(g<void(&)()>(0)) == 2, "Ouch"); ...@@ -68,7 +68,7 @@ static_assert(sizeof(g<void(&)()>(0)) == 2, "Ouch");
static_assert(sizeof(g<void(&&)()>(0)) == 2, "Ouch"); static_assert(sizeof(g<void(&&)()>(0)) == 2, "Ouch");
static_assert(sizeof(f<void, void>(0)) == 2, "Ouch"); static_assert(sizeof(f<void, void>(0)) == 2, "Ouch");
static_assert(sizeof(f<void(), void()>(0)) == 2, "Ouch"); static_assert(sizeof(f<void(), void()>(0)) == 2, "Ouch");
static_assert(sizeof(f<void() const, void() const>(0)) == 2, "Ouch"); //static_assert(sizeof(f<void() const, void() const>(0)) == 2, "Ouch");
static_assert(sizeof(f<int, void>(0)) == 2, "Ouch"); static_assert(sizeof(f<int, void>(0)) == 2, "Ouch");
static_assert(sizeof(f<void, int>(0)) == 2, "Ouch"); static_assert(sizeof(f<void, int>(0)) == 2, "Ouch");
static_assert(sizeof(f<C, void>(0)) == 2, "Ouch"); static_assert(sizeof(f<C, void>(0)) == 2, "Ouch");
...@@ -90,7 +90,7 @@ static_assert(sizeof(g2<void(&)()>(0)) == 2, "Ouch"); ...@@ -90,7 +90,7 @@ static_assert(sizeof(g2<void(&)()>(0)) == 2, "Ouch");
static_assert(sizeof(g2<void(&&)()>(0)) == 2, "Ouch"); static_assert(sizeof(g2<void(&&)()>(0)) == 2, "Ouch");
static_assert(sizeof(f2<void, void>(0)) == 2, "Ouch"); static_assert(sizeof(f2<void, void>(0)) == 2, "Ouch");
static_assert(sizeof(f2<void(), void()>(0)) == 2, "Ouch"); static_assert(sizeof(f2<void(), void()>(0)) == 2, "Ouch");
static_assert(sizeof(f2<void() const, void() const>(0)) == 2, "Ouch"); //static_assert(sizeof(f2<void() const, void() const>(0)) == 2, "Ouch");
static_assert(sizeof(f2<int, void>(0)) == 2, "Ouch"); static_assert(sizeof(f2<int, void>(0)) == 2, "Ouch");
static_assert(sizeof(f2<void, int>(0)) == 2, "Ouch"); static_assert(sizeof(f2<void, int>(0)) == 2, "Ouch");
static_assert(sizeof(f2<C, void>(0)) == 2, "Ouch"); static_assert(sizeof(f2<C, void>(0)) == 2, "Ouch");
......
// PR c++/48665
#include <typeinfo>
extern "C" void abort();
template<class A,class B> void f() {
if (typeid(A)==typeid(B)) abort(); // { dg-error "qualified function" }
if (typeid(A*)==typeid(B*)) abort(); // { dg-error "qualified function" }
}
int main() {
f<void()const,void()>();
}
2013-04-22 Jason Merrill <jason@redhat.com>
* testsuite/20_util/is_assignable/value.cc: Comment out tests involving
function-cv-quals.
* testsuite/20_util/is_constructible/value-2.cc: Likewise.
* testsuite/20_util/reference_wrapper/result_type.cc: Likewise.
* testsuite/20_util/reference_wrapper/typedefs-2.cc: Likewise.
2013-04-22 François Dumont <fdumont@gcc.gnu.org> 2013-04-22 François Dumont <fdumont@gcc.gnu.org>
* include/bits/hashtable_policy.h: Add C++11 allocator support. * include/bits/hashtable_policy.h: Add C++11 allocator support.
......
...@@ -277,8 +277,8 @@ static_assert(!std::is_assignable<DelAnyAssign&, int&>::value, "Error"); ...@@ -277,8 +277,8 @@ static_assert(!std::is_assignable<DelAnyAssign&, int&>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, const int&>::value, "Error"); static_assert(!std::is_assignable<DelAnyAssign&, const int&>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, void>::value, "Error"); static_assert(!std::is_assignable<DelAnyAssign&, void>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, void()>::value, "Error"); static_assert(!std::is_assignable<DelAnyAssign&, void()>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, void() // static_assert(!std::is_assignable<DelAnyAssign&, void()
const>::value, "Error"); // const>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, void(&)()>::value, "Error"); static_assert(!std::is_assignable<DelAnyAssign&, void(&)()>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, void(&&)()>::value, "Error"); static_assert(!std::is_assignable<DelAnyAssign&, void(&&)()>::value, "Error");
static_assert(!std::is_assignable<DelAnyAssign&, static_assert(!std::is_assignable<DelAnyAssign&,
...@@ -600,7 +600,7 @@ static_assert(std::is_assignable<UAssignAll&, ...@@ -600,7 +600,7 @@ static_assert(std::is_assignable<UAssignAll&,
std::nullptr_t&>::value, "Error"); std::nullptr_t&>::value, "Error");
static_assert(std::is_assignable<UAssignAll&, void()>::value, "Error"); static_assert(std::is_assignable<UAssignAll&, void()>::value, "Error");
static_assert(std::is_assignable<UAssignAll&, void(&)()>::value, "Error"); static_assert(std::is_assignable<UAssignAll&, void(&)()>::value, "Error");
static_assert(std::is_assignable<UAssignAll&, void() const>::value, "Error"); //static_assert(std::is_assignable<UAssignAll&, void() const>::value, "Error");
static_assert(std::is_assignable<UAssignAll&, void(*)()>::value, "Error"); static_assert(std::is_assignable<UAssignAll&, void(*)()>::value, "Error");
static_assert(std::is_assignable<UAssignAll&, void(*&)()>::value, "Error"); static_assert(std::is_assignable<UAssignAll&, void(*&)()>::value, "Error");
static_assert(std::is_assignable<UAssignAll&, int*>::value, "Error"); static_assert(std::is_assignable<UAssignAll&, int*>::value, "Error");
...@@ -636,8 +636,8 @@ static_assert(!std::is_assignable<UDelAssignAll&, ...@@ -636,8 +636,8 @@ static_assert(!std::is_assignable<UDelAssignAll&,
std::nullptr_t&>::value, "Error"); std::nullptr_t&>::value, "Error");
static_assert(!std::is_assignable<UDelAssignAll&, void()>::value, "Error"); static_assert(!std::is_assignable<UDelAssignAll&, void()>::value, "Error");
static_assert(!std::is_assignable<UDelAssignAll&, void(&)()>::value, "Error"); static_assert(!std::is_assignable<UDelAssignAll&, void(&)()>::value, "Error");
static_assert(!std::is_assignable<UDelAssignAll&, void() // static_assert(!std::is_assignable<UDelAssignAll&, void()
const>::value, "Error"); // const>::value, "Error");
static_assert(!std::is_assignable<UDelAssignAll&, void(*)()>::value, "Error"); static_assert(!std::is_assignable<UDelAssignAll&, void(*)()>::value, "Error");
static_assert(!std::is_assignable<UDelAssignAll&, void(*&)()>::value, "Error"); static_assert(!std::is_assignable<UDelAssignAll&, void(*&)()>::value, "Error");
static_assert(!std::is_assignable<UDelAssignAll&, int*>::value, "Error"); static_assert(!std::is_assignable<UDelAssignAll&, int*>::value, "Error");
......
...@@ -72,8 +72,8 @@ static_assert(!std::is_constructible<DelEllipsis, SE>::value, "Error"); ...@@ -72,8 +72,8 @@ static_assert(!std::is_constructible<DelEllipsis, SE>::value, "Error");
static_assert(!std::is_constructible<DelEllipsis, OpE>::value, "Error"); static_assert(!std::is_constructible<DelEllipsis, OpE>::value, "Error");
static_assert(!std::is_constructible<DelEllipsis, OpSE>::value, "Error"); static_assert(!std::is_constructible<DelEllipsis, OpSE>::value, "Error");
static_assert(!std::is_constructible<DelEllipsis, void()>::value, "Error"); static_assert(!std::is_constructible<DelEllipsis, void()>::value, "Error");
static_assert(!std::is_constructible<DelEllipsis, void() const>::value, // static_assert(!std::is_constructible<DelEllipsis, void() const>::value,
"Error"); // "Error");
static_assert(!std::is_constructible<DelEllipsis, int[1]>::value, "Error"); static_assert(!std::is_constructible<DelEllipsis, int[1]>::value, "Error");
static_assert(!std::is_constructible<DelEllipsis, int[]>::value, "Error"); static_assert(!std::is_constructible<DelEllipsis, int[]>::value, "Error");
static_assert(!std::is_constructible<DelEllipsis, int*>::value, "Error"); static_assert(!std::is_constructible<DelEllipsis, int*>::value, "Error");
...@@ -461,20 +461,20 @@ static_assert(!std::is_constructible<OpSE, void()>::value, "Error"); ...@@ -461,20 +461,20 @@ static_assert(!std::is_constructible<OpSE, void()>::value, "Error");
static_assert(!std::is_constructible<int[], void()>::value, "Error"); static_assert(!std::is_constructible<int[], void()>::value, "Error");
static_assert(!std::is_constructible<int[1], void()>::value, "Error"); static_assert(!std::is_constructible<int[1], void()>::value, "Error");
static_assert(!std::is_constructible<void(int) const, // static_assert(!std::is_constructible<void(int) const,
void() const>::value, "Error"); // void() const>::value, "Error");
static_assert(!std::is_constructible<int, void() const>::value, "Error"); // static_assert(!std::is_constructible<int, void() const>::value, "Error");
static_assert(!std::is_constructible<Abstract, void() const>::value, "Error"); // static_assert(!std::is_constructible<Abstract, void() const>::value, "Error");
static_assert(!std::is_constructible<std::nullptr_t, void() const>::value, // static_assert(!std::is_constructible<std::nullptr_t, void() const>::value,
"Error"); // "Error");
static_assert(!std::is_constructible<Empty, void() const>::value, "Error"); // static_assert(!std::is_constructible<Empty, void() const>::value, "Error");
static_assert(!std::is_constructible<U, void() const>::value, "Error"); // static_assert(!std::is_constructible<U, void() const>::value, "Error");
static_assert(!std::is_constructible<E, void() const>::value, "Error"); // static_assert(!std::is_constructible<E, void() const>::value, "Error");
static_assert(!std::is_constructible<SE, void() const>::value, "Error"); // static_assert(!std::is_constructible<SE, void() const>::value, "Error");
static_assert(!std::is_constructible<OpE, void() const>::value, "Error"); // static_assert(!std::is_constructible<OpE, void() const>::value, "Error");
static_assert(!std::is_constructible<OpSE, void() const>::value, "Error"); // static_assert(!std::is_constructible<OpSE, void() const>::value, "Error");
static_assert(!std::is_constructible<int[], void() const>::value, "Error"); // static_assert(!std::is_constructible<int[], void() const>::value, "Error");
static_assert(!std::is_constructible<int[1], void() const>::value, "Error"); // static_assert(!std::is_constructible<int[1], void() const>::value, "Error");
static_assert(!std::is_constructible<void, int, int>::value, "Error"); static_assert(!std::is_constructible<void, int, int>::value, "Error");
static_assert(!std::is_constructible<void, Empty, B>::value, "Error"); static_assert(!std::is_constructible<void, Empty, B>::value, "Error");
...@@ -488,8 +488,8 @@ static_assert(!std::is_constructible<void, int[], int[]>::value, "Error"); ...@@ -488,8 +488,8 @@ static_assert(!std::is_constructible<void, int[], int[]>::value, "Error");
static_assert(!std::is_constructible<void, void, int>::value, "Error"); static_assert(!std::is_constructible<void, void, int>::value, "Error");
static_assert(!std::is_constructible<void, void, void>::value, "Error"); static_assert(!std::is_constructible<void, void, void>::value, "Error");
static_assert(!std::is_constructible<void, void(), void()>::value, "Error"); static_assert(!std::is_constructible<void, void(), void()>::value, "Error");
static_assert(!std::is_constructible<void, void() const, // static_assert(!std::is_constructible<void, void() const,
void() volatile>::value, "Error"); // void() volatile>::value, "Error");
static_assert(!std::is_constructible<int, int, int>::value, "Error"); static_assert(!std::is_constructible<int, int, int>::value, "Error");
static_assert(!std::is_constructible<const int, int, int>::value, "Error"); static_assert(!std::is_constructible<const int, int, int>::value, "Error");
...@@ -651,13 +651,13 @@ static_assert(!std::is_constructible<void(), void, void>::value, "Error"); ...@@ -651,13 +651,13 @@ static_assert(!std::is_constructible<void(), void, void>::value, "Error");
static_assert(!std::is_constructible<void(), void(), int>::value, "Error"); static_assert(!std::is_constructible<void(), void(), int>::value, "Error");
static_assert(!std::is_constructible<void(), void(), void()>::value, "Error"); static_assert(!std::is_constructible<void(), void(), void()>::value, "Error");
static_assert(!std::is_constructible<void() const, int, int>::value, "Error"); // static_assert(!std::is_constructible<void() const, int, int>::value, "Error");
static_assert(!std::is_constructible<void() const, void, int>::value, "Error"); // static_assert(!std::is_constructible<void() const, void, int>::value, "Error");
static_assert(!std::is_constructible<void() const, void, void>::value, "Error"); // static_assert(!std::is_constructible<void() const, void, void>::value, "Error");
static_assert(!std::is_constructible<void() const, void() volatile, // static_assert(!std::is_constructible<void() const, void() volatile,
int>::value, "Error"); // int>::value, "Error");
static_assert(!std::is_constructible<void() const, void() volatile const, // static_assert(!std::is_constructible<void() const, void() volatile const,
void() const>::value, "Error"); // void() const>::value, "Error");
static_assert(!std::is_constructible<FromArgs<int>, int, int>::value, "Error"); static_assert(!std::is_constructible<FromArgs<int>, int, int>::value, "Error");
static_assert(!std::is_constructible<const FromArgs<int>, int, int>::value, static_assert(!std::is_constructible<const FromArgs<int>, int, int>::value,
......
...@@ -27,9 +27,9 @@ using namespace std; ...@@ -27,9 +27,9 @@ using namespace std;
struct T; struct T;
reference_wrapper<int(float, ...)>::result_type i01; reference_wrapper<int(float, ...)>::result_type i01;
reference_wrapper<int(float, ...) const>::result_type i02; // reference_wrapper<int(float, ...) const>::result_type i02;
reference_wrapper<int(float, ...) volatile>::result_type i03; // reference_wrapper<int(float, ...) volatile>::result_type i03;
reference_wrapper<int(float, ...) const volatile>::result_type i04; // reference_wrapper<int(float, ...) const volatile>::result_type i04;
reference_wrapper<int(*)(float, ...)>::result_type i05; reference_wrapper<int(*)(float, ...)>::result_type i05;
reference_wrapper<int(* const)(float, ...)>::result_type i06; reference_wrapper<int(* const)(float, ...)>::result_type i06;
......
...@@ -25,13 +25,13 @@ ...@@ -25,13 +25,13 @@
using namespace std; using namespace std;
reference_wrapper<int(float)>::argument_type i01; reference_wrapper<int(float)>::argument_type i01;
reference_wrapper<int(float) const>::argument_type i02; // reference_wrapper<int(float) const>::argument_type i02;
reference_wrapper<int(float) volatile>::argument_type i03; // reference_wrapper<int(float) volatile>::argument_type i03;
reference_wrapper<int(float) const volatile>::argument_type i04; // reference_wrapper<int(float) const volatile>::argument_type i04;
reference_wrapper<int(float)>::result_type i05; reference_wrapper<int(float)>::result_type i05;
reference_wrapper<int(float) const>::result_type i06; // reference_wrapper<int(float) const>::result_type i06;
reference_wrapper<int(float) volatile>::result_type i07; // reference_wrapper<int(float) volatile>::result_type i07;
reference_wrapper<int(float) const volatile>::result_type i08; // reference_wrapper<int(float) const volatile>::result_type i08;
reference_wrapper<int(*)(float)>::argument_type i09; reference_wrapper<int(*)(float)>::argument_type i09;
reference_wrapper<int(* const)(float)>::argument_type i10; reference_wrapper<int(* const)(float)>::argument_type i10;
...@@ -43,17 +43,17 @@ reference_wrapper<int(* volatile)(float)>::result_type i15; ...@@ -43,17 +43,17 @@ reference_wrapper<int(* volatile)(float)>::result_type i15;
reference_wrapper<int(* const volatile)(float)>::result_type i16; reference_wrapper<int(* const volatile)(float)>::result_type i16;
reference_wrapper<int(float, char)>::first_argument_type i17; reference_wrapper<int(float, char)>::first_argument_type i17;
reference_wrapper<int(float, char) const>::first_argument_type i18; // reference_wrapper<int(float, char) const>::first_argument_type i18;
reference_wrapper<int(float, char) volatile>::first_argument_type i19; // reference_wrapper<int(float, char) volatile>::first_argument_type i19;
reference_wrapper<int(float, char) const volatile>::first_argument_type i20; // reference_wrapper<int(float, char) const volatile>::first_argument_type i20;
reference_wrapper<int(float, char)>::second_argument_type i21; reference_wrapper<int(float, char)>::second_argument_type i21;
reference_wrapper<int(float, char) const>::second_argument_type i22; // reference_wrapper<int(float, char) const>::second_argument_type i22;
reference_wrapper<int(float, char) volatile>::second_argument_type i23; // reference_wrapper<int(float, char) volatile>::second_argument_type i23;
reference_wrapper<int(float, char) const volatile>::second_argument_type i24; // reference_wrapper<int(float, char) const volatile>::second_argument_type i24;
reference_wrapper<int(float, char)>::result_type i25; reference_wrapper<int(float, char)>::result_type i25;
reference_wrapper<int(float, char) const>::result_type i26; // reference_wrapper<int(float, char) const>::result_type i26;
reference_wrapper<int(float, char) volatile>::result_type i27; // reference_wrapper<int(float, char) volatile>::result_type i27;
reference_wrapper<int(float, char) const volatile>::result_type i28; // reference_wrapper<int(float, char) const volatile>::result_type i28;
reference_wrapper<int(*)(float, char)>::first_argument_type i29; reference_wrapper<int(*)(float, char)>::first_argument_type i29;
reference_wrapper<int(* const)(float, char)>::first_argument_type i30; reference_wrapper<int(* const)(float, char)>::first_argument_type i30;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment