[PING,PR46003,C++] Fix the assertion failure in build_target_expr

Message ID 000201cbcedb$e9ac8b70$bd05a250$@Zhang@arm.com
State New
Headers show

Commit Message

Yufeng Zhang Feb. 17, 2011, 7:50 p.m.

This patch fixes g++.dg/template/cond5.C failure with arm-eabi; the fix
is done in the C++ frontend.


Any comment will be appreciated.


-----Original Message-----

The test ./g++.dg/template/cond5.C fails for testing with arm-eabi with
an assertion failure, which occurs in cp/tree.c:build_target_expr(). 
(Please see the bugzilla page for more information on the analysis:

Note that the assertion does not fail in x86-targeted (or any of many
other targets targeted) compiler, because of the difference in the ARM C
++ ABI on constructor return values. The ARM C++ ABI requires C1 and C2
constructors to return this (instead of being void functions).

The patch tries to patch cp/tree.c:build_aggr_init_expr().
build_aggr_init_expr() wraps a ctor-calling CALL_EXPR tree node with an
AGGR_INIT_EXPR tree node, whose expression type is always VOID_TYPE. When
it determines whether the routine being called is a ctor or not, it only
looks into simple cases, but not the case of overloaded ctors in a tree
patch expands the is_ctor determining logic.
The test with arm-eabi before and after the patch shows that the
previously failing test (cond5.C) now passes, and all the other tests
are unaffected. There is no change in the x86 test result.

OK for the trunk?


2011-02-10  Yufeng Zhang  <yufeng.zhang@arm.com>

        PR c++/46003
        * tree.c (build_aggr_init_expr): Also consider overloaded ctors
        when determining is_ctor.


Index: gcc/cp/tree.c
--- gcc/cp/tree.c       (revision 169974)
+++ gcc/cp/tree.c       (working copy)
@@ -391,9 +391,11 @@ 
     return convert (type, init);
-  is_ctor = (TREE_CODE (fn) == ADDR_EXPR
-            && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
-            && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
+  is_ctor = ((TREE_CODE (fn) == ADDR_EXPR
+             && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
+             && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)))
+            || ((is_overloaded_fn (fn))
+                 && DECL_CONSTRUCTOR_P (get_first_fn (fn))));
   /* We split the CALL_EXPR into its function and its arguments here.
      Then, in expand_expr, we put them back together.  The reason for