diff options
author | Jason Merrill <jason@redhat.com> | 2010-02-16 01:05:20 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-02-16 01:05:20 -0500 |
commit | 1e2ddf80b6806a33e0043437466f9549e5f5bac2 (patch) | |
tree | e3b5c8c4521ed90808f9880d31e72252ba427cbe | |
parent | 38e40fcd450c508dbacdd2ddcd40ed1e500c4713 (diff) | |
download | gcc-1e2ddf80b6806a33e0043437466f9549e5f5bac2.zip gcc-1e2ddf80b6806a33e0043437466f9549e5f5bac2.tar.gz gcc-1e2ddf80b6806a33e0043437466f9549e5f5bac2.tar.bz2 |
re PR c++/43031 (internal compiler error: verify_gimple failed after non-trivial conversion error when crosscompiling Firefox)
PR c++/43031
* cp-gimplify.c (cp_gimplify_expr) [MODIFY_EXPR]: Use
VIEW_CONVERT_EXPR for conversions between structural equality types
that the back end can't tell are the same.
From-SVN: r156793
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attrib36.C | 20 |
4 files changed, 42 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8b9bc62..5b433f0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2010-02-16 Jason Merrill <jason@redhat.com> + PR c++/43031 + * cp-gimplify.c (cp_gimplify_expr) [MODIFY_EXPR]: Use + VIEW_CONVERT_EXPR for conversions between structural equality types + that the back end can't tell are the same. + PR c++/43036 * tree.c (build_cplus_array_type): Set TYPE_MAIN_VARIANT to strip cv-quals from element here. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index e0047cf..7dc79b2 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -552,6 +552,20 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 25979. */ case INIT_EXPR: cp_gimplify_init_expr (expr_p, pre_p, post_p); + /* Fall through. */ + case MODIFY_EXPR: + { + /* If the back end isn't clever enough to know that the lhs and rhs + types are the same, add an explicit conversion. */ + tree op0 = TREE_OPERAND (*expr_p, 0); + tree op1 = TREE_OPERAND (*expr_p, 1); + + if ((TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0)) + || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1))) + && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0))) + TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (op0), op1); + } ret = GS_OK; break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f361202..891acb1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-02-16 Jason Merrill <jason@redhat.com> + PR c++/43031 + * g++.dg/ext/attrib36.C: New. + PR c++/43036 * g++.dg/other/array6.C: New. diff --git a/gcc/testsuite/g++.dg/ext/attrib36.C b/gcc/testsuite/g++.dg/ext/attrib36.C new file mode 100644 index 0000000..a4ee209 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib36.C @@ -0,0 +1,20 @@ +// PR c++/43031 +// { dg-do compile { target i?86-*-* x86_64-*-* } } + +class T; +class L { }; +class P : public L +{ + typedef void (__attribute__((__stdcall__)) T::*F) (L*); + void f(bool aAdd); +}; +class T +{ +public: + virtual void __attribute__((__stdcall__)) A(L *listener) = 0; + virtual void __attribute__((__stdcall__)) R(L *listener) = 0; +}; +void P::f(bool aAdd) +{ + F addRemoveEventListener = (aAdd ? &T::A : &T::R); +} |