diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-07-26 19:34:33 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-07-29 17:10:09 +0200 |
commit | 7616ed6307c90b5bbf1bf53550d33cc674ab4b6f (patch) | |
tree | 54b64dfacbd3bd53468ab91c176a033cb390383a /gcc/d | |
parent | 5c9b7408dc578cb2ae142a5c1b724c183497bdb2 (diff) | |
download | gcc-7616ed6307c90b5bbf1bf53550d33cc674ab4b6f.zip gcc-7616ed6307c90b5bbf1bf53550d33cc674ab4b6f.tar.gz gcc-7616ed6307c90b5bbf1bf53550d33cc674ab4b6f.tar.bz2 |
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.
Diffstat (limited to 'gcc/d')
-rw-r--r-- | gcc/d/expr.cc | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 99ca958..85269c6 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); |