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.
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))
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. */
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;
}
--- /dev/null
+// 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();
+}