[PATCH] D136554: Implement CWG2631

Jordan Rupprecht via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 28 20:27:27 PST 2022


rupprecht added a comment.

I'm not sure what to make of the new failure when I try it out this time. Given a source like this:

  #include <functional>
  
  struct Options {
    std::function<bool(bool x)> identity = [](bool x) -> bool { return x; };
  };
  
  struct Wrapper {
    explicit Wrapper(const Options& options = Options()) {}
  };
  
  void Func() { Options options; }

The object file reports many fewer symbols as a result of this patch, but one new problematic one. Before:

  0000000000000000 T Func()
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::target_type() const
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::target(std::type_info const&) const
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::__clone(std::__1::__function::__base<bool (bool)>*) const
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::__clone() const
  0000000000000000 W std::__1::__function::__base<bool (bool)>::~__base[abi:v160000]()
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::destroy_deallocate()
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::destroy()
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::~__func()
  0000000000000000 W std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>::operator()(bool&&)
  0000000000000000 V typeinfo for Options::identity::'lambda'(bool)
  0000000000000000 V typeinfo for std::__1::__function::__base<bool (bool)>
  0000000000000000 V typeinfo for std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>
  0000000000000000 V typeinfo name for Options::identity::'lambda'(bool)
  0000000000000000 V typeinfo name for std::__1::__function::__base<bool (bool)>
  0000000000000000 V typeinfo name for std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>
                   U vtable for __cxxabiv1::__class_type_info
                   U vtable for __cxxabiv1::__si_class_type_info
  0000000000000000 V vtable for std::__1::__function::__func<Options::identity::'lambda'(bool), std::__1::allocator<Options::identity::'lambda'(bool)>, bool (bool)>
                   U operator delete(void*)
                   U operator new(unsigned long)

And after:

  0000000000000000 T Func()
                   U std::__1::function<bool (bool)>::function<Options::identity::'lambda'(bool), void>(Options::identity::'lambda'(bool))

The undefined symbols before are all provided by libc++, so those are fine. After, the new undefined symbol for the lambda cannot be resolved. Depending on how the linker is invoked, this may or may not be fine -- IIUC the linker can sometimes recognize that it doesn't actually need the undefined symbol, so it doesn't matter if it can't find it.

Here is the build script I'm using, although you will likely need to tweak it for your own environment:

  ${CLANG} \
    -std=gnu++17 -stdlib=libc++ \
    -c main.cc \
    -o /tmp/main.o
  
  echo "main.o symbols:"
  llvm-nm -C /tmp/main.o
  
  echo Building b.cc
  
  ${CLANG} \
    -std=gnu++17 -stdlib=libc++ \
    -O1 -fno-exceptions \
    -c b.cc \
    -o /tmp/b.o
  
  echo "b.o symbols:"
  llvm-nm -C /tmp/b.o
  
  echo Linking, and expecting success
  
  ${CLANG} \
    -fuse-ld=lld \
    -o /tmp/main \
    /tmp/main.o \
    -Wl,--start-lib /tmp/b.o -Wl,--end-lib \
    /usr/lib/x86_64-linux-gnu/libc++.so
  
  echo Linking, and expecting failure with D136554
  
  ${CLANG} \
    -fuse-ld=lld \
    -o /tmp/main \
    /tmp/main.o \
    /tmp/b.o \
    /usr/lib/x86_64-linux-gnu/libc++.so \
    -Wl,--export-dynamic

(Here `b.cc` is the first snippet above, and `main.cc` is a trivial file with just `int main(int argc, char* argv[]) { return 0; }`)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136554/new/

https://reviews.llvm.org/D136554



More information about the cfe-commits mailing list