False Negatives Wunused-function in clang found by gcc

By building llvm-project with gcc 7 and 10, I found multiple Wunused-function warnings that clang 11/12 missed.

All of these warnings were recently introduced, and the authors fixed many of them. Any ideas why clang misses so many of this category? And why the ones missed are recent changes to the llvm codebase?

-Luke

Not sure where the regression might’ve leaked in. But does seem to be something to do with anonymous namespace support and member functions: https://godbolt.org/z/zz8WP1

Not sure where the regression might've leaked in. But does seem to be something to do with anonymous namespace support and member functions: Compiler Explorer

I don't think there's a regression here, unless I'm missing something.
-Wunused-member-function is what diagnoses this
(Compiler Explorer) but it is not a subgroup of either
-Wunused-function or -Wunused
(https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/DiagnosticGroups.td#L839).
Perhaps we should explicitly enable it?

~Aaron

Any reason it shouldn’t be a subgroup of -Wunused-function? I guess maybe because people already had codebases that were -Wunused-function clean, and we wouldn’t want to regress that/start warning on new things/force them to have to add -Wno-unused-member-function to unbreak their builds?

(I guess there’s some history here? Like perhaps -Wunused-function was initially implemented without member function support, and it was added later & so added under a separate flag to make rollout easier? But I think it’d probably still be OK for it to be under a subgroup - people could opt out of it initially without losing all their existing -Wunused-function-cleanliness, and opt in if they ever decided to do the extra cleanup)

Any reason it shouldn't be a subgroup of -Wunused-function? I guess maybe because people already had codebases that were -Wunused-function clean, and we wouldn't want to regress that/start warning on new things/force them to have to add -Wno-unused-member-function to unbreak their builds?

(I guess there's some history here? Like perhaps -Wunused-function was initially implemented without member function support, and it was added later & so added under a separate flag to make rollout easier? But I think it'd probably still be OK for it to be under a subgroup - people could opt out of it initially without losing all their existing -Wunused-function-cleanliness, and opt in if they ever decided to do the extra cleanup)

Here is the commit that introduced the feature (under a different flag
that was later renamed to -Wunused-member-function):
https://github.com/llvm/llvm-project/commit/cad715fb9bfd50370fa22ca62634048dcc85598b
but I was not able to locate the discussion about the patch from the
list archives.

It looks like the big reason it's not under -Wunused is because the
LLVM codebase isn't ready to handle it, but given that 11 years have
passed, I feel like it would be reasonable to revisit the warning
groups. Logically, I would expect -Wunused-function to include
-Wunused-member-function and I would expect -Wunused to include them
both. If LLVM is not able to handle that change, we can alter our
CMake files.

~Aaron

Yep, +1 to that.

Hello,

I have an embedded application for ARM architecture and I want to embed into it the lld linker. I have downloaded clang+llvm-11.0.1-armv7a-linux-gnueabihf.tar.xz and I have tried to add the following function to my application:

bool testLlvm()
{
printf("test llvm\n");
llvm::ArrayRef<const char*> args;
bool canExitEarly = true;
std::string s, t;
llvm::raw_string_ostream stdoutOS(s);
llvm::raw_string_ostream stderrOS(t);
bool ret = lld::elf::link(args, canExitEarly, stdoutOS, stderrOS);
printf("Output: %s\n", stdoutOS.str().c_str());
printf("Error: %s\n", stderrOS.str().c_str());
return ret;
}

The embedded application is compiled using gcc, and I tried to link it to the llvm libraries. For linking I used all libraries liblld*.a and all libraries libLLVM*.a, however I got many linking errors of undefined symbols (listed at the end of the message).

Is it possible to link the existing llvm binary to the existing application using gcc? If so, what libraries are missing? Should I compile also llvm with gcc?

Actually, I realized now there is "linux" in the name of the binary distribution. My embedded device does not have Linux.

Is it possible at all to achieve this? The application compiler must be gcc.

Best regards,

Viorel

undefined reference to `__ctype_b_loc'
undefined reference to `__ctype_toupper_loc'
undefined reference to `__errno_location'
undefined reference to `__lxstat64'
undefined reference to `__once_proxy'
undefined reference to `__sched_cpucount'
undefined reference to `__tls_get_addr'
undefined reference to `__xstat64'
undefined reference to `_execve'
undefined reference to `_fork'
undefined reference to `_gettimeofday'
undefined reference to `_link'
undefined reference to `_stat'
undefined reference to `_unlink'
undefined reference to `_wait'
undefined reference to `alarm'
undefined reference to `bool std::__detail::__regex_algo_impl
undefined reference to `chdir'
undefined reference to `closedir'
undefined reference to `del_curterm'
undefined reference to `dlclose'
undefined reference to `dlerror'
undefined reference to `dlopen'
undefined reference to `dlsym'
undefined reference to `dup2'
undefined reference to `execv'
undefined reference to `fetestexcept'
undefined reference to `ftruncate64'
undefined reference to `getcwd'
undefined reference to `getpagesize'
undefined reference to `getPollyPluginInfo()'
undefined reference to `getpwnam'
undefined reference to `getpwuid'
undefined reference to `getrlimit64'
undefined reference to `getrusage'
undefined reference to `getuid'
undefined reference to `lseek64'
undefined reference to `lstat64'
undefined reference to `mkdir'
undefined reference to `mmap64'
undefined reference to `mprotect'
undefined reference to `munmap'
undefined reference to `open64'
undefined reference to `opendir'
undefined reference to `posix_fallocate64'
undefined reference to `posix_spawn'
undefined reference to `posix_spawn_file_actions_adddup2'
undefined reference to `posix_spawn_file_actions_addopen'
undefined reference to `posix_spawn_file_actions_destroy'
undefined reference to `posix_spawn_file_actions_init'
undefined reference to `pread64'
undefined reference to `pthread_create'
undefined reference to `pthread_getname_np'
undefined reference to `pthread_rwlock_unlock'
undefined reference to `pthread_rwlock_wrlock'
undefined reference to `pthread_self'
undefined reference to `pthread_sigmask'
undefined reference to `readdir64'
undefined reference to `readlink'
undefined reference to `realpath'
undefined reference to `sched_getaffinity'
undefined reference to `set_curterm'
undefined reference to `setrlimit64'
undefined reference to `setupterm'
undefined reference to `sigaction'
undefined reference to `sigaltstack'
undefined reference to `sigemptyset'
undefined reference to `sigfillset'
undefined reference to `sigprocmask'
undefined reference to `stat64'
undefined reference to `statfs64'
undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_wait_until(unsigned int*
undefined reference to `std::__future_base::_Result_base::_Result_base()'
undefined reference to `std::__future_base::_Result_base::~_Result_base()'
undefined reference to `std::__future_base::_State_baseV2::_Make_ready::_M_set()'
undefined reference to `std::__once_call'
undefined reference to `std::__once_callable'
undefined reference to `std::condition_variable::~condition_variable()'
undefined reference to `std::condition_variable::condition_variable()'
undefined reference to `std::condition_variable::notify_all()'
undefined reference to `std::condition_variable::notify_one()'
undefined reference to `std::condition_variable::wait(std::unique_lock<std::mutex>&)'
undefined reference to `std::thread::_M_start_thread(std::unique_ptr<std::thread::_State
undefined reference to `std::thread::_State::~_State()'
undefined reference to `std::thread::detach()'
undefined reference to `std::thread::hardware_concurrency()'
undefined reference to `std::thread::join()'
undefined reference to `stderr'
undefined reference to `stdin'
undefined reference to `stdout'
undefined reference to `syscall'
undefined reference to `tigetnum'
undefined reference to `uname'
undefined reference to `void std::vector<std::__cxx11::basic_string<char
undefined reference to `wait4'