]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
Fix compilation with libcxx 16 144/head
authorRobert Schulze <robert@clickhouse.com>
Tue, 28 Mar 2023 21:34:35 +0000 (21:34 +0000)
committerRobert Schulze <robert@clickhouse.com>
Tue, 28 Mar 2023 21:58:44 +0000 (21:58 +0000)
After upgrading our (ClickHouse's) libcxx from 15 to 16, the compiler
started to complain about usage of an incomplete type "RoseInstruction"
in this (header) function:

  void RoseProgram::replace(Iter it, std::unique_ptr<RoseInstruction> ri) {
    ...

The reason is that libcxx 16 is the first version which implements C++23
constexpr std::unique_ptr (P2273R3, see (*)). RoseProgram::replace()
happens to be be const-evaluatable and the compiler tries to run
std::unique_ptr's ctor + dtor. This fails because at this point
RoseInstruction isn't defined yet.

There are two ways of fixing this:
1. Include rose_build_instruction.h (which contains RoseInstruction)
   into rose_build_program.h. Disadvantage: The new include will
   propagate transitively into all callers.
2. Move the function implementation into the source file which sees
   RoseInstruction's definition already. Disadvantage: Template
   instantiation is no longer automatic, instead there must be either a)
   explicit template instantiation (e.g. in rose_build_program.cpp) or
   b) all callers which instantiate the function must live in the same
   source file and do the instantiations by themselves. Fortunately, the
   latter is the case here, but potential future code outside
   rose_build_program.cpp will require ugly explicit instantiation.

(*) https://en.cppreference.com/w/cpp/23

src/rose/rose_build_program.cpp
src/rose/rose_build_program.h

index 3ddf2fcdc3a22f9da0b943de7f31f22b0851f58f..8e179e3610ba7b783bbc91f95867118afac855bc 100644 (file)
@@ -204,6 +204,15 @@ void RoseProgram::add_block(RoseProgram &&block) {
                 make_move_iterator(block.prog.end()));
 }
 
+template<class Iter>
+void RoseProgram::replace(Iter it, std::unique_ptr<RoseInstruction> ri) {
+    assert(!prog.empty());
+
+    const RoseInstruction *old_ptr = it->get();
+    *it = move(ri);
+    update_targets(prog.begin(), prog.end(), old_ptr, it->get());
+}
+
 bytecode_ptr<char> writeProgram(RoseEngineBlob &blob,
                                 const RoseProgram &program) {
     u32 total_len = 0;
index 6ad5529c3ba115b600f81e4d7a7ad656f29c9a79..1882279ddef0460639d71be5676a2754b83fde11 100644 (file)
@@ -124,13 +124,7 @@ public:
      * \brief Replace the instruction pointed to by the given iterator.
      */
     template<class Iter>
-    void replace(Iter it, std::unique_ptr<RoseInstruction> ri) {
-        assert(!prog.empty());
-
-        const RoseInstruction *old_ptr = it->get();
-        *it = move(ri);
-        update_targets(prog.begin(), prog.end(), old_ptr, it->get());
-    }
+    void replace(Iter it, std::unique_ptr<RoseInstruction> ri);
 };
 
 bytecode_ptr<char> writeProgram(RoseEngineBlob &blob,