From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12177 invoked by alias); 10 Feb 2011 17:36:29 -0000 Received: (qmail 12056 invoked by uid 22791); 10 Feb 2011 17:36:28 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 10 Feb 2011 17:36:23 +0000 From: "yufeng.zhang at arm dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/46003] cond5.C fails for ARM EABI tests. X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Keywords: ice-on-valid-code X-Bugzilla-Severity: normal X-Bugzilla-Who: yufeng.zhang at arm dot com X-Bugzilla-Status: NEW X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Date: Thu, 10 Feb 2011 17:36:00 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2011-02/txt/msg01338.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46003 --- Comment #3 from Yufeng Zhang 2011-02-10 17:36:12 UTC --- The repro can be reduced to: ------------ CODE ------------ struct A { A(int); }; template void foo(A& x) { 0 ? x : 0; } ------------ CUT ------------ The assertion failure occurs in cp/tree.c:build_target_expr(tree decl, tree value), which is expecting the TREE_TYPE of the VALUE to meet one of the following conditions: 1. is VOID_TYPE 2. is the same as the type of the DECL, which is to be initialized with the VALUE 3. passes useless_type_conversion_p() The assertions fails when the TREE_TYPE of the VALUE is found to be POINTER_TYPE, while the DECL has VOID_TYPE. Note that the assertion does not fail in the 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). During the parsing of an conditional expression, the C++ front-end needs to determine the expression type, especially when the 2nd and 3rd operands are of different types. For 0 ? x : 0 in the repro code, it seems that ctors (constructors) of A (including the user defined ctor and the compiler generated copy ctor) are invoked to convert the type of the 3rd operand from INTEGER_TYPE to the RECORD_TYPE of A. This is part of the process in order to match the type of the 3rd operand to that of the 2nd one. When the assertion happens, the VALUE is the following like tree node: CALL_EXPR (pointer_type to struct A) COMPONENT_REF (pointer_type to method_type of a method in A) INDIRECT_REF (record_type of A) INTEGER_CST 0 (pointer_type to A) BASELINK OVERLOAD A* A::A(const A&) A* A::A(int) TARGET_EXPR (record_type of A) VAR_DECL AGGR_INIT_EXPR (void_type) op0: (A*)0 op1: (int)0 func: ADDR_EXPR (method_type) FUNCTION_DECL __comp_ctor A* A::A(int) Basically what the tree is doing is: ((A)0).A((A*)0->A(0)) i.e. construct a temporary object of A by explicitly calling the user-defined ctor, and pass it to the copy ctor of A to construct another temporary object of A, but this time replying on the overload resolution to get the copy ctor selected. Leave aside the kids nodes of the CALL_EXPR tree node, and focus on its TREE_TYPE, which is the return type of the routine to be called. Because the routine is a ctor and the compiler targets ARM, it has the TREE_TYPE of POINTER_TYPE (conforming to the ABI). When the CALL_EXPR tree node is passed to build_target_expr as the VALUE to initialize the DECL, which sensibly has the type of RECORD_TYPE (of A), the compiler complains: mismatching types!! You cannot use a tree node of POINTER_TYPE to initialize a RECORD_TYPE tree node! In x86-targeted GCC, however, such a CALL_EXPR tree node has VOID_TYPE as a ctor returns void as specified by the generic C++ ABI, and thus the assertion failure will not happen.