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

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

Reply via email to