llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Vassil Vassilev (vgvassilev) <details> <summary>Changes</summary> This patch brings back the basic support for C by inserting the required for value printing runtime only when we are in C++ mode. Additionally, it defines a new overload of operator placement new because we can't really forward declare it in a library-agnostic way. Fixes the issue described in llvm/llvm-project#<!-- -->69072. --- Full diff: https://github.com/llvm/llvm-project/pull/76218.diff 2 Files Affected: - (modified) clang/lib/Interpreter/Interpreter.cpp (+16-2) - (modified) clang/test/Interpreter/incremental-mode.cpp (+2-1) ``````````diff diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index c9fcef5b5b5af1..daceabafe4c938 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -248,7 +248,7 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( - void* operator new(__SIZE_TYPE__, void* __p) noexcept; +#ifdef __cplusplus void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); @@ -256,15 +256,18 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); + struct __clang_Interpreter_NewTag{}; + void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template <class T, class = T (*)() /*disable for arrays*/> void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) { for (auto Idx = 0; Idx < Size; ++Idx) - new ((void*)(((T*)Placement) + Idx)) T(Src[Idx]); + new ((void*)(((T*)Placement) + Idx), __clang_Interpreter_NewTag()) T(Src[Idx]); } template <class T, unsigned long N> void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +#endif // __cplusplus )"; llvm::Expected<std::unique_ptr<Interpreter>> @@ -814,3 +817,14 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, VRef = Value(static_cast<Interpreter *>(This), OpaqueType); VRef.setLongDouble(Val); } + +// A trampoline to work around the fact that operator placement new cannot +// really be forward declared due to libc++ and libstdc++ declaration mismatch. +// FIXME: __clang_Interpreter_NewTag is ODR violation because we get the same +// definition in the interpreter runtime. We should move it in a runtime header +// which gets included by the interpreter and here. +struct __clang_Interpreter_NewTag{}; +void* operator new(__SIZE_TYPE__ __sz, void* __p, __clang_Interpreter_NewTag) noexcept { + // Just forward to the standard operator placement new. + return operator new(__sz, __p); +} diff --git a/clang/test/Interpreter/incremental-mode.cpp b/clang/test/Interpreter/incremental-mode.cpp index e6350d237ef578..d63cee0dd6d15f 100644 --- a/clang/test/Interpreter/incremental-mode.cpp +++ b/clang/test/Interpreter/incremental-mode.cpp @@ -1,3 +1,4 @@ // RUN: clang-repl -Xcc -E -// RUN: clang-repl -Xcc -emit-llvm +// RUN: clang-repl -Xcc -emit-llvm +// RUN: clang-repl -Xcc -xc // expected-no-diagnostics `````````` </details> https://github.com/llvm/llvm-project/pull/76218 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits