This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG7c215a457178: [clang][Interp] Explicitly handle RVO Pointer (authored by tbaeder).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137392/new/ https://reviews.llvm.org/D137392 Files: clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpFrame.cpp clang/lib/AST/Interp/InterpFrame.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/records.cpp
Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -131,6 +131,12 @@ return C(); } constexpr C RVOAndParamsResult = RVOAndParams(&c); + +/// Parameter and return value have different types. +constexpr C RVOAndParams(int a) { + return C(); +} +constexpr C RVOAndParamsResult2 = RVOAndParams(12); #endif class Bar { // expected-note {{definition of 'Bar' is not complete}} \ Index: clang/lib/AST/Interp/Opcodes.td =================================================================== --- clang/lib/AST/Interp/Opcodes.td +++ clang/lib/AST/Interp/Opcodes.td @@ -269,6 +269,9 @@ // [] -> [Pointer] def This : Opcode; +// [] -> [Pointer] +def RVOPtr : Opcode; + // [Pointer] -> [Pointer] def NarrowPtr : Opcode; // [Pointer] -> [Pointer] Index: clang/lib/AST/Interp/InterpFrame.h =================================================================== --- clang/lib/AST/Interp/InterpFrame.h +++ clang/lib/AST/Interp/InterpFrame.h @@ -37,7 +37,8 @@ /// Creates a new frame with the values that make sense. /// I.e., the caller is the current frame of S, - /// and the This() pointer is the current Pointer on the top of S's stack, + /// the This() pointer is the current Pointer on the top of S's stack, + /// and the RVO pointer is before that. InterpFrame(InterpState &S, const Function *Func, CodePtr RetPC); /// Destroys the frame, killing all live pointers to stack slots. @@ -101,6 +102,9 @@ /// Returns the 'this' pointer. const Pointer &getThis() const { return This; } + /// Returns the RVO pointer, if the Function has one. + const Pointer &getRVOPtr() const { return RVOPtr; } + /// Checks if the frame is a root frame - return should quit the interpreter. bool isRoot() const { return !Func; } @@ -139,6 +143,8 @@ const Function *Func; /// Current object pointer for methods. Pointer This; + /// Pointer the non-primitive return value gets constructed in. + Pointer RVOPtr; /// Return address. CodePtr RetPC; /// The size of all the arguments. Index: clang/lib/AST/Interp/InterpFrame.cpp =================================================================== --- clang/lib/AST/Interp/InterpFrame.cpp +++ clang/lib/AST/Interp/InterpFrame.cpp @@ -49,6 +49,9 @@ // If the fuction has a This pointer, that one is next. // Then follow the actual arguments (but those are handled // in getParamPointer()). + if (Func->hasRVO()) + RVOPtr = stackRef<Pointer>(0); + if (Func->hasThisPointer()) { if (Func->hasRVO()) This = stackRef<Pointer>(sizeof(Pointer)); Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -1148,6 +1148,12 @@ return true; } +inline bool RVOPtr(InterpState &S, CodePtr OpPC) { + assert(S.Current->getFunction()->hasRVO()); + S.Stk.push<Pointer>(S.Current->getRVOPtr()); + return true; +} + //===----------------------------------------------------------------------===// // Shr, Shl //===----------------------------------------------------------------------===// Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -233,8 +233,13 @@ return this->emitRet(*ReturnType, RS); } else { // RVO - construct the value in the return location. + if (!this->emitRVOPtr(RE)) + return false; if (!this->visitInitializer(RE)) return false; + if (!this->emitPopPtr(RE)) + return false; + this->emitCleanup(); return this->emitRetVoid(RS); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits