From ed8574ce3b466ebf5af4656750fcb06b8ff607bf Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Mon, 7 Feb 2022 17:00:23 +0100 Subject: [PATCH] [clang] use NRVO information at ReturnStmt level isElidable at ConstructorExpr is not used in this case in clang-13 --- ClangVisitor.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/ClangVisitor.cpp b/ClangVisitor.cpp index 1fcd7ff6..452446f6 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(); -- GitLab