From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 80A1439B3C31; Thu, 29 Jul 2021 15:12:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80A1439B3C31 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-2598] d: Return the correct value for C++ constructor calls (PR101664) X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/master X-Git-Oldrev: 5c9b7408dc578cb2ae142a5c1b724c183497bdb2 X-Git-Newrev: 7616ed6307c90b5bbf1bf53550d33cc674ab4b6f Message-Id: <20210729151259.80A1439B3C31@sourceware.org> Date: Thu, 29 Jul 2021 15:12:59 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Jul 2021 15:12:59 -0000 https://gcc.gnu.org/g:7616ed6307c90b5bbf1bf53550d33cc674ab4b6f commit r12-2598-g7616ed6307c90b5bbf1bf53550d33cc674ab4b6f Author: Iain Buclaw Date: Mon Jul 26 19:34:33 2021 +0200 d: Return the correct value for C++ constructor calls (PR101664) C++ constructors return void, even though the front-end semantic treats them as implicitly returning `this'. To handle this correctly, the object reference is cached and used as the result of the expression. PR d/101664 gcc/d/ChangeLog: * expr.cc (ExprVisitor::visit (CallExp *)): Use object expression as result for C++ constructor calls. gcc/testsuite/ChangeLog: * gdc.dg/extern-c++/extern-c++.exp: New. * gdc.dg/extern-c++/pr101664.d: New test. * gdc.dg/extern-c++/pr101664_1.cc: New test. Diff: --- gcc/d/expr.cc | 13 +++++++++ gcc/testsuite/gdc.dg/extern-c++/extern-c++.exp | 39 ++++++++++++++++++++++++++ gcc/testsuite/gdc.dg/extern-c++/pr101664.d | 15 ++++++++++ gcc/testsuite/gdc.dg/extern-c++/pr101664_1.cc | 10 +++++++ 4 files changed, 77 insertions(+) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 99ca958c7c4..85269c6b2be 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1751,6 +1751,7 @@ public: tree callee = NULL_TREE; tree object = NULL_TREE; tree cleanup = NULL_TREE; + tree returnvalue = NULL_TREE; TypeFunction *tf = NULL; /* Calls to delegates can sometimes look like this. */ @@ -1819,6 +1820,15 @@ public: else fndecl = build_address (fndecl); + /* C++ constructors return void, even though front-end semantic + treats them as implicitly returning `this'. Set returnvalue + to override the result of this expression. */ + if (fd->isCtorDeclaration () && fd->linkage == LINKcpp) + { + thisexp = d_save_expr (thisexp); + returnvalue = thisexp; + } + callee = build_method_call (fndecl, thisexp, fd->type); } } @@ -1885,6 +1895,9 @@ public: build the call expression. */ tree exp = d_build_call (tf, callee, object, e->arguments); + if (returnvalue != NULL_TREE) + exp = compound_expr (exp, returnvalue); + if (tf->isref) exp = build_deref (exp); diff --git a/gcc/testsuite/gdc.dg/extern-c++/extern-c++.exp b/gcc/testsuite/gdc.dg/extern-c++/extern-c++.exp new file mode 100644 index 00000000000..d38f993faaf --- /dev/null +++ b/gcc/testsuite/gdc.dg/extern-c++/extern-c++.exp @@ -0,0 +1,39 @@ +# Copyright (C) 2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Load support procs. +load_lib gdc-dg.exp + +# We are mixing D and C++ code, need to pull in libstdc++ +global GDC_INCLUDE_CXX_FLAGS +set GDC_INCLUDE_CXX_FLAGS 1 + +# Initialize `dg'. +dg-init + +# Main loop. +if [check_no_compiler_messages extern_c++_tests assembly { + // C++ + int main() { return 0; } +}] { + gdc-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/*.d ] ] "" "" +} + +set GDC_INCLUDE_CXX_FLAGS 0 + +# All done. +dg-finish diff --git a/gcc/testsuite/gdc.dg/extern-c++/pr101664.d b/gcc/testsuite/gdc.dg/extern-c++/pr101664.d new file mode 100644 index 00000000000..57b3d903582 --- /dev/null +++ b/gcc/testsuite/gdc.dg/extern-c++/pr101664.d @@ -0,0 +1,15 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101664 +// { dg-do run } +// { dg-options "-O2" } +// { dg-additional-sources "pr101664_1.cc" } + +extern(C++) struct S101664 +{ + int i; + this(int); +} + +void main() +{ + assert(S101664(1).i == 1); +} diff --git a/gcc/testsuite/gdc.dg/extern-c++/pr101664_1.cc b/gcc/testsuite/gdc.dg/extern-c++/pr101664_1.cc new file mode 100644 index 00000000000..066e784293d --- /dev/null +++ b/gcc/testsuite/gdc.dg/extern-c++/pr101664_1.cc @@ -0,0 +1,10 @@ +struct S101664 +{ + int i; + S101664 (int n); +}; + +S101664::S101664 (int n) + : i(n) +{ +}