[clang] afa60d0 - [clang][Interp] Fix discarding non-primitive function call return values

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 30 00:18:54 PST 2022


Author: Timm Bäder
Date: 2022-11-30T09:18:28+01:00
New Revision: afa60d08a2d4e99cec6cacdcdc36d568ac2b3118

URL: https://github.com/llvm/llvm-project/commit/afa60d08a2d4e99cec6cacdcdc36d568ac2b3118
DIFF: https://github.com/llvm/llvm-project/commit/afa60d08a2d4e99cec6cacdcdc36d568ac2b3118.diff

LOG: [clang][Interp] Fix discarding non-primitive function call return values

Differential Revision: https://reviews.llvm.org/D136457

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/test/AST/Interp/records.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 0d5c26c7634a3..c727893e5a6f1 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1150,6 +1150,19 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
     if (Func->isFullyCompiled() && !Func->isConstexpr())
       return false;
 
+    QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
+    Optional<PrimType> 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<unsigned> 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<Emitter>::VisitCallExpr(const CallExpr *E) {
     if (!this->emitCall(Func, E))
       return false;
 
-    QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
-    if (DiscardResult && !ReturnType->isVoidType()) {
-      Optional<PrimType> 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 63e957a9d0459..963a3f1d636fd 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 {


        


More information about the cfe-commits mailing list