diff --git a/ClangVisitor.cpp b/ClangVisitor.cpp
index 1fcd7ff6f3ed2328c2b5d31c6515fefff1c61fdd..452446f60db4b4be7c6c6958ecfc2d581399494f 100644
--- a/ClangVisitor.cpp
+++ b/ClangVisitor.cpp
@@ -24,7 +24,12 @@
 // Description:
 //   Definition of a translator clang -> intermediate_format (-> cabs -> cil).
 //
-
+extern "C" {
+#include "intermediate_format.h"
+};
+#include <clang/AST/Expr.h>
+#include <clang/AST/ExprCXX.h>
+#include <llvm/Support/Casting.h>
 #ifdef __GNUC__
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wclass-memaccess"
@@ -3910,9 +3915,23 @@ statement FramacVisitor::makeReturnStmt(
   bool* shouldDelay) {
   // implicit precondition: commentLocation != NULL => stmts != NULL
   // the reverse is not true any more thanks to cleanups
-  const clang::Expr* re = returnStmt->getRetValue();
-  expression result = re ? makeLocExpression(re, shouldDelay) : NULL;
-  option e = re ? opt_some_container(result) : opt_none();
+  option e = opt_none();
+  expression result = NULL;
+  const clang::VarDecl* v = returnStmt->getNRVOCandidate();
+  if (v && v->isNRVOVariable()) {
+    // The returned expression should be a CXXConstructorExpr, which
+    // is not marked as elidable since clang 13.0. Hence, do the elision here
+    const clang::CXXConstructExpr* ce =
+        llvm::dyn_cast<clang::CXXConstructExpr>(returnStmt->getRetValue());
+    assert(ce && ce->getNumArgs() == 1);
+    const clang::Expr *re = ce->getArg(0);
+    result = makeLocExpression(re,shouldDelay);
+  }
+  else {
+    const clang::Expr* re = returnStmt->getRetValue();
+    if (re) result = makeLocExpression(re, shouldDelay);
+  }
+  if (result) e = opt_some_container(result);
   if (stmts || !_cleanups.empty()) {
     /* statement */ list* cursor = forwardStmts.getBack()
       ? &forwardStmts.getBack()->next : &forwardStmts.getFront();