Commit 62245e6f by Jason Merrill Committed by Jason Merrill

re PR c++/65880 (Member function issue with argument "pointer to const array of…

re PR c++/65880 (Member function issue with argument "pointer to const array of member function pointers")

	PR c++/65880
	* decl.c (build_ptrmemfunc_type): Check TYPE_GET_PTRMEMFUNC_TYPE after
	cv-qualifiers.
	* typeck.c (merge_types): build_ptrmemfunc_type before applying
	quals and attributes.

From-SVN: r224678
parent 30ac6e80
2015-06-19 Jason Merrill <jason@redhat.com>
PR c++/65880
* decl.c (build_ptrmemfunc_type): Check TYPE_GET_PTRMEMFUNC_TYPE after
cv-qualifiers.
* typeck.c (merge_types): build_ptrmemfunc_type before applying
quals and attributes.
PR c++/65973
* constexpr.c (build_constexpr_constructor_member_initializers):
Handle an empty STATEMENT_LIST.
......
......@@ -8224,13 +8224,6 @@ build_ptrmemfunc_type (tree type)
if (type == error_mark_node)
return type;
/* If a canonical type already exists for this type, use it. We use
this method instead of type_hash_canon, because it only does a
simple equality check on the list of field members. */
if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type)))
return t;
/* Make sure that we always have the unqualified pointer-to-member
type first. */
if (cp_cv_quals quals = cp_type_quals (type))
......@@ -8239,6 +8232,13 @@ build_ptrmemfunc_type (tree type)
return cp_build_qualified_type (unqual, quals);
}
/* If a canonical type already exists for this type, use it. We use
this method instead of type_hash_canon, because it only does a
simple equality check on the list of field members. */
if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type)))
return t;
t = make_node (RECORD_TYPE);
/* Let the front end know this is a pointer to member function. */
......
......@@ -786,15 +786,16 @@ merge_types (tree t1, tree t2)
int quals = cp_type_quals (t1);
if (code1 == POINTER_TYPE)
t1 = build_pointer_type (target);
{
t1 = build_pointer_type (target);
if (TREE_CODE (target) == METHOD_TYPE)
t1 = build_ptrmemfunc_type (t1);
}
else
t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
t1 = build_type_attribute_variant (t1, attributes);
t1 = cp_build_qualified_type (t1, quals);
if (TREE_CODE (target) == METHOD_TYPE)
t1 = build_ptrmemfunc_type (t1);
return t1;
}
......
// PR c++/65880
class Test
{
public:
Test();
~Test();
bool barl(void);
private:
bool fool(bool (Test::* const *fms)(void));
bool foo(void);
bool bar(void);
};
Test::Test()
{
}
Test::~Test()
{
}
bool Test::fool(bool (Test::* const *fms)(void))
{
bool retval = false;
int i = 0;
bool (Test::*f)(void) = fms[i++];
while (f) {
retval = (this->*f)();
if (retval) break;
f = fms[i++];
}
return retval;
}
bool Test::barl(void)
{
static bool (Test::* const fms[])(void) = {
&Test::foo,
&Test::bar,
0
};
return fool(fms);
}
bool Test::foo(void)
{
return false;
}
bool Test::bar(void)
{
return true;
}
int main(int argc, const char *argv[])
{
Test t;
return t.barl();
}
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