re PR c++/9381 (attribute on member function pointer have no effect)
PR c++/9381 * decl2.c (build_memfn_type): Preserve attributes. * tree.c (canonical_type_variant): Likewise. * call.c (standard_conversion): Use build_memfn_type. * pt.c (tsubst): Likewise. * decl.c (build_ptrmem_type): Likewise From-SVN: r153998
This commit is contained in:
parent
ea61a28777
commit
5ca4325837
|
@ -1,3 +1,12 @@
|
|||
2009-11-06 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/9381
|
||||
* decl2.c (build_memfn_type): Preserve attributes.
|
||||
* tree.c (canonical_type_variant): Likewise.
|
||||
* call.c (standard_conversion): Use build_memfn_type.
|
||||
* pt.c (tsubst): Likewise.
|
||||
* decl.c (build_ptrmem_type): Likewise
|
||||
|
||||
2009-11-06 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/41967
|
||||
|
|
|
@ -887,10 +887,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
|
|||
|| cp_type_quals (fbase) != cp_type_quals (tbase))
|
||||
return NULL;
|
||||
|
||||
from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
|
||||
from = build_method_type_directly (from,
|
||||
TREE_TYPE (fromfn),
|
||||
TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
|
||||
from = build_memfn_type (fromfn, tbase, cp_type_quals (tbase));
|
||||
from = build_ptrmemfunc_type (build_pointer_type (from));
|
||||
conv = build_conv (ck_pmem, from, conv);
|
||||
conv->base_p = true;
|
||||
|
|
|
@ -7133,16 +7133,9 @@ build_ptrmem_type (tree class_type, tree member_type)
|
|||
{
|
||||
if (TREE_CODE (member_type) == METHOD_TYPE)
|
||||
{
|
||||
tree arg_types;
|
||||
|
||||
arg_types = TYPE_ARG_TYPES (member_type);
|
||||
class_type = (cp_build_qualified_type
|
||||
(class_type,
|
||||
cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)))));
|
||||
member_type
|
||||
= build_method_type_directly (class_type,
|
||||
TREE_TYPE (member_type),
|
||||
TREE_CHAIN (arg_types));
|
||||
tree arg_types = TYPE_ARG_TYPES (member_type);
|
||||
cp_cv_quals quals = cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)));
|
||||
member_type = build_memfn_type (member_type, class_type, quals);
|
||||
return build_ptrmemfunc_type (build_pointer_type (member_type));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -108,20 +108,27 @@ tree
|
|||
build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
|
||||
{
|
||||
tree raises;
|
||||
tree attrs;
|
||||
int type_quals;
|
||||
|
||||
if (fntype == error_mark_node || ctype == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
|
||||
|| TREE_CODE (fntype) == METHOD_TYPE);
|
||||
|
||||
type_quals = quals & ~TYPE_QUAL_RESTRICT;
|
||||
ctype = cp_build_qualified_type (ctype, type_quals);
|
||||
raises = TYPE_RAISES_EXCEPTIONS (fntype);
|
||||
attrs = TYPE_ATTRIBUTES (fntype);
|
||||
fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
|
||||
(TREE_CODE (fntype) == METHOD_TYPE
|
||||
? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
|
||||
: TYPE_ARG_TYPES (fntype)));
|
||||
raises = TYPE_RAISES_EXCEPTIONS (fntype);
|
||||
if (raises)
|
||||
fntype = build_exception_variant (fntype, raises);
|
||||
if (attrs)
|
||||
fntype = cp_build_type_attribute_variant (fntype, attrs);
|
||||
|
||||
return fntype;
|
||||
}
|
||||
|
|
|
@ -9602,13 +9602,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
|||
{
|
||||
/* The type of the implicit object parameter gets its
|
||||
cv-qualifiers from the FUNCTION_TYPE. */
|
||||
tree method_type;
|
||||
tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
|
||||
cp_type_quals (type));
|
||||
tree memptr;
|
||||
method_type = build_method_type_directly (this_type,
|
||||
TREE_TYPE (type),
|
||||
TYPE_ARG_TYPES (type));
|
||||
tree method_type = build_memfn_type (type, r, cp_type_quals (type));
|
||||
memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
|
||||
return cp_build_qualified_type_real (memptr, cp_type_quals (t),
|
||||
complain);
|
||||
|
|
|
@ -922,10 +922,14 @@ cp_build_qualified_type_real (tree type,
|
|||
tree
|
||||
canonical_type_variant (tree t)
|
||||
{
|
||||
tree r;
|
||||
|
||||
if (t == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t));
|
||||
r = cp_build_type_attribute_variant (TYPE_MAIN_VARIANT (t),
|
||||
TYPE_ATTRIBUTES (t));
|
||||
return cp_build_qualified_type (r, cp_type_quals (t));
|
||||
}
|
||||
|
||||
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-11-06 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/9381
|
||||
* g++.dg/abi/regparm1.C: New.
|
||||
|
||||
2009-11-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/41643
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// PR c++/29911 (9381)
|
||||
// { dg-options -std=c++0x }
|
||||
// { dg-do run { target i?86-*-* x86_64-*-* } }
|
||||
|
||||
extern "C" int printf(const char *, ...);
|
||||
|
||||
void *save_this;
|
||||
int *save_addr1, *save_addr2;
|
||||
|
||||
struct Base
|
||||
{
|
||||
__attribute((regparm(3))) void
|
||||
set(int *addr1, int *addr2)
|
||||
{
|
||||
if (this != save_this)
|
||||
printf("error! this == %p, should be %p\n", this, save_this);
|
||||
if (addr1 != save_addr1)
|
||||
printf("error! addr1 == %p, should be %p\n", addr1, save_addr1);
|
||||
if (addr2 != save_addr2)
|
||||
printf("error! addr2 == %p, should be %p\n", addr2, save_addr1);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
void (__attribute((regparm(3))) Base::* pfm)(int *, int *) = &Base::set;
|
||||
__typeof (&Base::set) pfm2 = &Base::set;
|
||||
decltype (&Base::set) pfm3 = &Base::set;
|
||||
auto pfm4 = &Base::set;
|
||||
|
||||
Base obj; save_this = &obj;
|
||||
int x, y; save_addr1 = &x; save_addr2 = &y;
|
||||
|
||||
(obj.* pfm) (&x, &y);
|
||||
(obj.* pfm2) (&x, &y);
|
||||
(obj.* pfm3) (&x, &y);
|
||||
(obj.* pfm4) (&x, &y);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue