From patchwork Wed Oct 3 08:07:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 188726 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 8AC152C00E4 for ; Wed, 3 Oct 2012 18:07:55 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1349856475; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=5gs78IeuvtHxJ/02cI8V APkJhLA=; b=t5kDULFDoftgLtddg2Msuc+aCb7jh0sqbVrxxYFzkbiN4Xh554FK BL7aUlvpgs0HxT8OC19mtS6acfXFCprmWBM5cggyfJ5AwUPv9sweEj9r2GKFE6Ex +jg0ZLmi+FGzoEeyesUNgXXxqyf8XGt/+U2rI5xfhce3A1sKQn4NtRA= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type:Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=G7jP6nahKNAyDGKYeSyXivnbKSa2T/s3WwZX9HsZbf1CoYfUBV8ARXcPNZ4OHY oigVAqnuhh9LerqugPgMo3RcyMkfXYRykKlJnGOSal86RdKmdCA7yBZuo67QrShg +n/1ICsNBZhCmL7SOgHNXNyKoTEMbYFVSNMw63bFzoyA8=; Received: (qmail 30149 invoked by alias); 3 Oct 2012 08:07:49 -0000 Received: (qmail 30130 invoked by uid 22791); 3 Oct 2012 08:07:46 -0000 X-SWARE-Spam-Status: No, hits=-0.5 required=5.0 tests=AWL, BAYES_50, RCVD_IN_HOSTKARMA_NO, TW_TM X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 03 Oct 2012 08:07:41 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 7A0F41C760E; Wed, 3 Oct 2012 04:07:40 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id nCbCDa5kMkYy; Wed, 3 Oct 2012 04:07:40 -0400 (EDT) Received: from kwai.gnat.com (kwai.gnat.com [205.232.38.4]) by rock.gnat.com (Postfix) with ESMTP id 614811C75FD; Wed, 3 Oct 2012 04:07:40 -0400 (EDT) Received: by kwai.gnat.com (Postfix, from userid 4192) id 6118C3FF09; Wed, 3 Oct 2012 04:07:40 -0400 (EDT) Date: Wed, 3 Oct 2012 04:07:40 -0400 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Javier Miranda Subject: [Ada] Ada/C++ missing call to constructor with defaults Message-ID: <20121003080740.GA28803@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org When the type of an object is a CPP untagged type and the object initialization requires calling its default C++ constructor, the Ada compiler did not generate the call to a C++ constructor which has all parameters with defaults (and hence it covers the default C++ constructor). // c_class.h class Tester { public: Tester(unsigned int a_num = 5, char* a_className = 0); }; // c_class.cc #include "c_class.h" #include Tester::Tester(unsigned int a_num, char* a_className) { std::cout << " ctor Tester called " << a_num << ":"; if (a_className == 0) { std::cout << "null"; } else { std::cout << a_className; } std::cout << std::endl; } -- c_class_h.ads with Interfaces.C; use Interfaces.C; with Interfaces.C.Strings; package c_class_h is package Class_Tester is type Tester is limited record null; end record; pragma Import (CPP, Tester); function New_Tester -- Modified by hand (a_num : unsigned := 5; a_className : Interfaces.C.Strings.chars_ptr := Interfaces.C.Strings.Null_Ptr) return Tester; -- c_class.h:3 pragma CPP_Constructor (New_Tester, "_ZN6TesterC1EjPc"); end; use Class_Tester; end c_class_h; -- main.adb with c_class_h; use c_class_h; procedure Main is use Class_Tester; Ptr : access Tester := new Tester; -- TEST pragma Unreferenced (Ptr); begin null; end main; -- ada2cpp.gpr project Ada2Cppc is for Languages use ("Ada", "C++"); for Main use ("main.adb"); package Naming is for Implementation_Suffix ("C++") use ".cc"; end Naming; for Source_Dirs use ("."); for Object_Dir use "obj"; package Compiler is for Default_Switches ("ada") use ("-g", "-gnato", "-gnatwa", "-gnatQ", "-gnat05", "-gnatD"); end Compiler; package Builder is for Default_Switches ("ada") use ("-g"); end Builder; package Ide is for Compiler_Command ("ada") use "gnatmake"; for Compiler_Command ("c") use "gcc"; end Ide; end Ada2Cppc; Command: gprbuild -q -P ada2cppc.gpr; obj/main Output: ctor Tester called 5:null Tested on x86_64-pc-linux-gnu, committed on trunk 2012-10-03 Javier Miranda * exp_disp.adb (Set_CPP_Constructors_Old): Handle constructor of untagged type that has all its parameters with defaults and hence it covers the default constructor. Index: exp_disp.adb =================================================================== --- exp_disp.adb (revision 192025) +++ exp_disp.adb (working copy) @@ -8459,6 +8459,8 @@ P : Node_Id; Parms : List_Id; + Covers_Default_Constructor : Entity_Id := Empty; + begin -- Look for the constructor entities @@ -8490,7 +8492,8 @@ Make_Defining_Identifier (Loc, Chars (Defining_Identifier (P))), Parameter_Type => - New_Copy_Tree (Parameter_Type (P)))); + New_Copy_Tree (Parameter_Type (P)), + Expression => New_Copy_Tree (Expression (P)))); Next (P); end loop; end if; @@ -8508,6 +8511,17 @@ Set_Convention (Init, Convention_CPP); Set_Is_Public (Init); Set_Has_Completion (Init); + + -- If this constructor has parameters and all its parameters + -- have defaults then it covers the default constructor. The + -- semantic analyzer ensures that only one constructor with + -- defaults covers the default constructor. + + if Present (Parameter_Specifications (Parent (E))) + and then Needs_No_Actuals (E) + then + Covers_Default_Constructor := Init; + end if; end if; Next_Entity (E); @@ -8519,6 +8533,49 @@ if not Found then Set_Is_Abstract_Type (Typ); end if; + + -- Handle constructor that has all its parameters with defaults and + -- hence it covers the default constructor. We generate a wrapper IP + -- which calls the covering constructor. + + if Present (Covers_Default_Constructor) then + declare + Body_Stmts : List_Id; + Wrapper_Id : Entity_Id; + Wrapper_Body_Node : Node_Id; + begin + Loc := Sloc (Covers_Default_Constructor); + + Body_Stmts := New_List ( + Make_Procedure_Call_Statement (Loc, + Name => New_Reference_To (Covers_Default_Constructor, Loc), + Parameter_Associations => New_List ( + Make_Identifier (Loc, Name_uInit)))); + + Wrapper_Id := Make_Defining_Identifier (Loc, + Make_Init_Proc_Name (Typ)); + + Wrapper_Body_Node := + Make_Subprogram_Body (Loc, + Specification => + Make_Procedure_Specification (Loc, + Defining_Unit_Name => Wrapper_Id, + Parameter_Specifications => New_List ( + Make_Parameter_Specification (Loc, + Defining_Identifier => + Make_Defining_Identifier (Loc, Name_uInit), + Parameter_Type => + New_Reference_To (Typ, Loc)))), + Declarations => No_List, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => Body_Stmts, + Exception_Handlers => No_List)); + + Discard_Node (Wrapper_Body_Node); + Set_Init_Proc (Typ, Wrapper_Id); + end; + end if; end Set_CPP_Constructors_Old; -- Local variables