Author: David Spickett
Date: 2025-08-13T12:55:40Z
New Revision: dece902a52c01ed386f63ce0ead6b781a630e580

URL: 
https://github.com/llvm/llvm-project/commit/dece902a52c01ed386f63ce0ead6b781a630e580
DIFF: 
https://github.com/llvm/llvm-project/commit/dece902a52c01ed386f63ce0ead6b781a630e580.diff

LOG: [lldb][MCP] Fix compiler error in Windows on Arm build

Caused by https://github.com/llvm/llvm-project/pull/153297.

This is likely not Windows on Arm specific but the other Windows bots
don't have this problem.

json::parse tries to construct llvm::Expected<Message> by moving another
instance of Message into it. This would normally use this constructor:
```
  /// Create an Expected<T> success value from the given OtherT value, which
  /// must be convertible to T.
  template <typename OtherT>
  Expected(OtherT &&Val,
           std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
<...>
```
Note that llvm::Expected does not have a T&& constructor. Presumably
the authors thought the converting one would be used.

Except that in our build, using clang-cl 19.1.7, Visual Studio 2022,
MSVC STL 202208, somehow is_convertible_v is false for Message.

If you add a static_assert to check that this is the case, it suddenly
becomes convertible. As best I can understand, this is because evaluation
of the properties of Message are delayed. Delayed so much that by the time
the constructor is called, it's still false.

So we can "fix" this by asserting that it is convertible some time before
it is checked by the constructor.

I'm not sure if that's a compiler problem or the way MSVC STL's variant is
written. I couldn't reproduce this behaviour in smaller examples or on Linux
systems. This is the least invasive fix and only touches the new lldb code,
so I'm going with it.

Including the whole error here because it's a strange one and maybe later
someone who has a clue about this can fix it in a better way.

```
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build>ninja
[5/15] Building CXX object 
tools\lldb\source\Pro...CP\CMakeFiles\lldbProtocolMCP.dir\Server.cpp.obj
FAILED: 
tools/lldb/source/Protocol/MCP/CMakeFiles/lldbProtocolMCP.dir/Server.cpp.obj
C:\Users\tcwg\scoop\shims\ccache.exe 
C:\Users\tcwg\scoop\apps\llvm-arm64\current\bin\clang-cl.exe  /nologo -TP 
-DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE 
-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS 
-D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_HAS_EXCEPTIONS=0 
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\source\Protocol\MCP
 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Protocol\MCP
 -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include 
-IC:\Users\tcwg\scoop\apps\python\current\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\..\clang\include
 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\..\clang\include
 -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\source 
/DWIN32 /D_WINDOWS   /Zc:inline /Zc:__cplusplus /Oi /Brepro /bigobj 
/permissive- -Werror=unguarded-availability-new /W4  -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type 
-Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override 
-Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported /Gw 
-Wno-vla-extension /O2 /Ob2 /DNDEBUG -std:c++17 -MD   -wd4018 -wd4068 -wd4150 
-wd4201 -wd4251 -wd4521 -wd4530 -wd4589  /EHs-c- /GR- /showIncludes 
/Fotools\lldb\source\Protocol\MCP\CMakeFiles\lldbProtocolMCP.dir\Server.cpp.obj 
/Fdtools\lldb\source\Protocol\MCP\CMakeFiles\lldbProtocolMCP.dir\lldbProtocolMCP.pdb
 -c -- 
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Protocol\MCP\Server.cpp
In file included from 
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Protocol\MCP\Server.cpp:9:
In file included from 
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include\lldb/Protocol/MCP/Server.h:12:
In file included from 
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include\lldb/Protocol/MCP/Protocol.h:17:
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/JSON.h(938,12):
 error: no viable conversion from returned value of type 
'remove_reference_t<variant<Request, Response, Notification> &>' (aka 
'std::variant<lldb_protocol::mcp::Request, lldb_protocol::mcp::Response, 
lldb_protocol::mcp::Notification>') to function return type 
'Expected<variant<Request, Response, Notification>>'
  938 |     return std::move(Result);
      |            ^~~~~~~~~~~~~~~~~
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Protocol\MCP\Server.cpp(57,30):
 note: in instantiation of function template specialization 
'llvm::json::parse<std::variant<lldb_protocol::mcp::Request, 
lldb_protocol::mcp::Response, lldb_protocol::mcp::Notification>>' requested here
   57 |   auto message = llvm::json::parse<Message>(/*JSON=*/data);
      |                              ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(485,40):
 note: candidate constructor (the implicit copy constructor) not viable: no 
known conversion from 'remove_reference_t<variant<Request, Response, 
Notification> &>' (aka 'std::variant<lldb_protocol::mcp::Request, 
lldb_protocol::mcp::Response, lldb_protocol::mcp::Notification>') to 'const 
Expected<variant<Request, Response, Notification>> &' for 1st argument
  485 | template <class T> class [[nodiscard]] Expected {
      |                                        ^~~~~~~~
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(507,3):
 note: candidate constructor not viable: no known conversion from 
'remove_reference_t<variant<Request, Response, Notification> &>' (aka 
'std::variant<lldb_protocol::mcp::Request, lldb_protocol::mcp::Response, 
lldb_protocol::mcp::Notification>') to 'Error &&' for 1st argument
  507 |   Expected(Error &&Err)
      |   ^        ~~~~~~~~~~~
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(521,3):
 note: candidate constructor not viable: no known conversion from 
'remove_reference_t<variant<Request, Response, Notification> &>' (aka 
'std::variant<lldb_protocol::mcp::Request, lldb_protocol::mcp::Response, 
lldb_protocol::mcp::Notification>') to 'ErrorSuccess' for 1st argument
  521 |   Expected(ErrorSuccess) = delete;
      |   ^        ~~~~~~~~~~~~
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(539,3):
 note: candidate constructor not viable: no known conversion from 
'remove_reference_t<variant<Request, Response, Notification> &>' (aka 
'std::variant<lldb_protocol::mcp::Request, lldb_protocol::mcp::Response, 
lldb_protocol::mcp::Notification>') to 'Expected<variant<Request, Response, 
Notification>> &&' for 1st argument
  539 |   Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
      |   ^        ~~~~~~~~~~~~~~~~
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(526,3):
 note: candidate template ignored: requirement 
'std::is_convertible_v<std::variant<lldb_protocol::mcp::Request, 
lldb_protocol::mcp::Response, lldb_protocol::mcp::Notification>, 
std::variant<lldb_protocol::mcp::Request, lldb_protocol::mcp::Response, 
lldb_protocol::mcp::Notification>>' was not satisfied [with OtherT = 
remove_reference_t<variant<Request, Response, Notification> &>]
  526 |   Expected(OtherT &&Val,
      |   ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(544,3):
 note: candidate template ignored: could not match 'Expected' against 'variant'
  544 |   Expected(Expected<OtherT> &&Other,
      |   ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include\llvm/Support/Error.h(552,12):
 note: explicit constructor is not a candidate
  552 |   explicit Expected(
      |            ^
1 error generated.
[8/15] Building CXX object 
tools\lldb\source\Plu...nProtocolServerMCP.dir\ProtocolServerMCP.cpp.obj
ninja: build stopped: subcommand failed.
```

Added: 
    

Modified: 
    lldb/include/lldb/Protocol/MCP/Protocol.h

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Protocol/MCP/Protocol.h 
b/lldb/include/lldb/Protocol/MCP/Protocol.h
index 141d064804e1e..49f9490221755 100644
--- a/lldb/include/lldb/Protocol/MCP/Protocol.h
+++ b/lldb/include/lldb/Protocol/MCP/Protocol.h
@@ -86,6 +86,10 @@ bool operator==(const Notification &, const Notification &);
 
 /// A general message as defined by the JSON-RPC 2.0 spec.
 using Message = std::variant<Request, Response, Notification>;
+// With clang-cl and MSVC STL 202208, convertible can be false later if we do
+// not force it to be checked early here.
+static_assert(std::is_convertible_v<Message, Message>,
+              "Message is not convertible to itself");
 
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to