Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1151,6 +1151,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)) @@ -1163,13 +1176,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 { Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -214,6 +214,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 {