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:
Jason Merrill 2009-11-07 14:45:56 -05:00 committed by Jason Merrill
parent ea61a28777
commit 5ca4325837
8 changed files with 72 additions and 22 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}