From afa60d08a2d4e99cec6cacdcdc36d568ac2b3118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Fri, 21 Oct 2022 17:32:39 +0200 Subject: [PATCH] [clang][Interp] Fix discarding non-primitive function call return values Differential Revision: https://reviews.llvm.org/D136457 --- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 22 +++++++++++++++------- clang/test/AST/Interp/records.cpp | 4 ++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 0d5c26c7634a33..c727893e5a6f1c 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1150,6 +1150,19 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { 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 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { 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 index 63e957a9d04595..963a3f1d636fd0 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -228,6 +228,10 @@ struct S { 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 {