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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits