diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1150,6 +1150,19 @@ if (Func->isFullyCompiled() && !Func->isConstexpr()) return false; + QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); + Optional T = classify(ReturnType); + + if (Func->hasRVO() && DiscardResult) { + // If we need to discard the return value but the function returns its + // value via an RVO pointer, we need to create one such pointer just + // for this call. + if (Optional LocalIndex = allocateLocal(E)) { + if (!this->emitGetPtrLocal(*LocalIndex, E)) + return false; + } + } + // Put arguments on the stack. for (const auto *Arg : E->arguments()) { if (!this->visit(Arg)) @@ -1162,13 +1175,8 @@ if (!this->emitCall(Func, E)) return false; - QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); - if (DiscardResult && !ReturnType->isVoidType()) { - Optional T = classify(ReturnType); - if (T) - return this->emitPop(*T, E); - // TODO: This is a RVO function and we need to ignore the return value. - } + if (DiscardResult && !ReturnType->isVoidType() && T) + return this->emitPop(*T, E); return true; } else { diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -228,6 +228,10 @@ this->a; // expected-warning {{expression result unused}} \ // ref-warning {{expression result unused}} get5(); +#if __cplusplus >= 201703L + // FIXME: Enable once we support MaterializeConstantExpr properly. + getInts(); +#endif } constexpr int m() const {