Commit 8bd20621 by Jason Merrill Committed by Jason Merrill

re PR c++/37016 (member function pointer failure with optimization)

        PR c++/37016
        * tree-ssa.c (useless_type_conversion_p_1): Call langhook
        if TYPE_STRUCTURAL_EQUALITY_P is true for both types.

From-SVN: r138740
parent 8a24bf04
2008-08-04 Jason Merrill <jason@redhat.com>
PR c++/37016
* tree-ssa.c (useless_type_conversion_p_1): Call langhook
if TYPE_STRUCTURAL_EQUALITY_P is true for both types.
2008-08-05 Richard Henderson <rth@redhat.com>
* configure.ac (HAVE_GAS_CFI_DIRECTIVE): Check .cfi_personality.
......
// PR c++/37016
// { dg-do run }
// { dg-options "-O2 -Wall" }
/*
Basic design concept is that WorldObject implements remote method call
functionality using the "curiously recurring template pattern" to enable
forwarding calls from the generic base class that implements the transport
layer to the derived class.
The specific failure was in forwarding calls to items in a container.
This is emulated here by wrapping a single item.
In the main program there are two forms of the call. In the last
(uncommented) form the member function pointer is for clarity
assigned to a variable (itemfunptr) before making the call.
With 4.3.0 and 4.3.1 this code compiles incorrectly with -O1 or greater
to produce this warning
reproduce.cc: In function ‘int main()’:
reproduce.cc:26: warning: ‘itemfunptr.void (Container::*)(void
(Item::*)(int), int)::__pfn’ is used uninitialized in this function
reproduce.cc:47: note: ‘itemfunptr.void (Container::*)(void (Item::*)(int),
int)::__pfn’ was declared here
and the resulting executable segvs. It works correctly with -O0.
With 4.2.3 and earlier it works correctly with optimization.
In the first (commented out) form of the call in the main program
we directly refer to desired member function. This compiles
and executes correctly with all tested versions.
*/
extern "C" int printf (const char *, ...);
template <class Derived>
struct WorldObject {
template <typename memfunT, typename arg1T, typename arg2T>
void forward(memfunT memfun, arg1T arg1, arg2T arg2) {
Derived* obj = static_cast<Derived*>(this);
(obj->*memfun)(arg1, arg2);
}
};
struct Item {
void fred(int a) {
printf ("a=%d\n", a);
}
};
struct Container : public WorldObject<Container> {
Item item;
template <typename itemfunT, typename arg1T>
void itemfun(itemfunT itemfun, int a) {
(item.*itemfun)(a);
}
};
int main() {
typedef void (Item::*itemfun)(int);
Container t;
// This call compiles and executes correctly with all versions tested
//t.forward(&Container::itemfun<itemfun,int>, &Item::fred, 1);
// This call compiles with a warning and segvs on execution if using
// -O1 or greater with 4.3.*. 4.2.* is correct.
void (Container::*itemfunptr)(itemfun, int) =
&Container::itemfun<itemfun,int>;
t.forward(itemfunptr, &Item::fred, 1);
return 0;
}
......@@ -1165,12 +1165,18 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
if (TREE_CODE (inner_type) != TREE_CODE (outer_type))
return false;
/* ??? Add structural equivalence check. */
/* ??? This seems to be necessary even for aggregates that don't
have TYPE_STRUCTURAL_EQUALITY_P set. */
/* ??? This should eventually just return false. */
return lang_hooks.types_compatible_p (inner_type, outer_type);
}
/* Also for functions and possibly other types with
TYPE_STRUCTURAL_EQUALITY_P set. */
else if (TYPE_STRUCTURAL_EQUALITY_P (inner_type)
&& TYPE_STRUCTURAL_EQUALITY_P (outer_type))
return lang_hooks.types_compatible_p (inner_type, outer_type);
return false;
}
......
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