diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 2326480fe2ea..a5dfaaf31965 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -90,6 +90,8 @@ bool InitLink::emit(Compiler *Ctx, const Expr *E) const { if (!Ctx->emitConstUint32(Offset, E)) return false; return Ctx->emitArrayElemPtrPopUint32(E); + case K_RVO: + return Ctx->emitRVOPtr(E); case K_InitList: return true; default: @@ -4998,6 +5000,7 @@ bool Compiler::visitReturnStmt(const ReturnStmt *RS) { if (!this->visit(RE)) return false; } else { + InitLinkScope ILS(this, InitLink::RVO()); // RVO - construct the value in the return location. if (!this->emitRVOPtr(RE)) return false; diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 2d5b76f78954..f9a597a16ef4 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -51,11 +51,13 @@ public: K_Temp = 2, K_Decl = 3, K_Elem = 5, - K_InitList = 6 + K_RVO = 6, + K_InitList = 7 }; static InitLink This() { return InitLink{K_This}; } static InitLink InitList() { return InitLink{K_InitList}; } + static InitLink RVO() { return InitLink{K_RVO}; } static InitLink Field(unsigned Offset) { InitLink IL{K_Field}; IL.Offset = Offset; diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index 86b58283023b..23582e9ab556 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -174,3 +174,14 @@ void lambdas() { int d; int a9[1] = {[d = 0] = 1}; // both-error {{not an integral constant expression}} } + + +namespace InitLinkToRVO { + struct A { + int y = 3; + int z = 1 + y; + }; + + constexpr A make() { return A {}; } + static_assert(make().z == 4, ""); +}