diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 01c0168d61a4..8fe0061a9025 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9931,10 +9931,19 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, return false; // Avoid materializing a temporary for an elidable copy/move constructor. - if (E->isElidable() && !ZeroInit) - if (const MaterializeTemporaryExpr *ME - = dyn_cast<MaterializeTemporaryExpr>(E->getArg(0))) + if (E->isElidable() && !ZeroInit) { + // FIXME: This only handles the simplest case, where the source object + // is passed directly as the first argument to the constructor. + // This should also handle stepping though implicit casts and + // and conversion sequences which involve two steps, with a + // conversion operator followed by a converting constructor. + const Expr *SrcObj = E->getArg(0); + assert(SrcObj->isTemporaryObject(Info.Ctx, FD->getParent())); + assert(Info.Ctx.hasSameUnqualifiedType(E->getType(), SrcObj->getType())); + if (const MaterializeTemporaryExpr *ME = + dyn_cast<MaterializeTemporaryExpr>(SrcObj)) return Visit(ME->getSubExpr()); + } if (ZeroInit && !ZeroInitialization(E, T)) return false; |