aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-07-26 19:34:33 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2021-07-29 17:10:09 +0200
commit7616ed6307c90b5bbf1bf53550d33cc674ab4b6f (patch)
tree54b64dfacbd3bd53468ab91c176a033cb390383a /gcc/d
parent5c9b7408dc578cb2ae142a5c1b724c183497bdb2 (diff)
downloadgcc-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.cc13
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);