(In reply to Andreas Nordal from comment #6) > The confusing thing was that clangd defeated my sanity check > (-Iweird_include worked when -std=c++17 did not). That's indeed confusing. > When reducing the problem again, it seems to be a header name collision > between newlib and host headers (cross compilation). Presumably newlib is a glibc replacement? In that case you might consider adding -nostdinc and specifying all necessary include directories manually to make sure they don't mix. > New reproducer (not reduced to a single header): > > Install /usr/riscv64-elf/include > > zypper in cross-riscv64-newlib-devel > > /tmp/compile_commands.json: > > [{ > "directory": "/tmp", > "command": "clang++ -std=c++17 -isystem /usr/riscv64-elf/include -c > takes_string_view.cpp -o takes_string_view.o", > "file": "takes_string_view.cpp" > }] > > /tmp/takes_string_view.cpp: > > #include <cstdlib> // Not relevant, but erases string_view. > #include <string_view> > > void f(std::string_view str); // No member named 'string_view' in > namespace 'std' That doesn't work for me with standalone clang: $ clang++ -std=c++17 -isystem /usr/riscv64-elf/include -c takes_string_view.cpp -o takes_string_view.o In file included from takes_string_view.cpp:1: In file included from /usr/bin/../lib64/gcc/x86_64-suse-linux/12/../../../../include/c++/12/cstdlib:75: /usr/include/stdlib.h:98:53: error: expected function body after function declarator extern size_t __ctype_get_mb_cur_max (void) __THROW __wur; ^ [...] Now line 75 has "#include_next <stdlib.h>", and since it works without "-isystem /usr/riscv64-elf/include", a previous include is the issue. Compiling with -E reveals that we go off the beaten path here: # 490 "/usr/include/features.h" 3 4 # 1 "/usr/riscv64-elf/include/sys/cdefs.h" 1 3 4 Now in glibc's /usr/include/sys/cdefs.h we find # define __wur __attribute_warn_unused_result__ but there is no definition in /usr/riscv64-elf/include/sys/cdefs.h. So I think you need to make sure to not mix glibc and newlib. I'm not sure if libstdc++ can deal with newlib though. Of course with -nostdinc you'll have to add the headers manually, you can find out which with -v on a regular compilation. As a side note: if you're observing the same, what you're seeing is likely just a follow-up error. For IDEs, only errors in the current file are typically printed, and clangd might just swallow all these earlier errors in system headers and print this error when coming back. Another problem: this compiles the riscv64 newlib to your native target. Now I assume that word sizes are the same, but there might be other difficulties. For true cross-compilation you need to add --target=riscv64-suse-linux-gnu. With libstdc++ I then end up with takes_string_view.cpp:1:10: fatal error: 'cstdlib' file not found #include <cstdlib> // Not relevant, but erases string_view. ^~~~~~~~~ because Clang doesn't find the header directories suitable for cross compilation (likely because it doesn't find a replacement for /usr/include/c++/12/x86_64-suse-linux/, not sure where I might get that). With -stdlib=libc++ I end up with lots of errors like this: In file included from takes_string_view.cpp:2: In file included from /usr/bin/../include/c++/v1/string_view:206: In file included from /usr/bin/../include/c++/v1/algorithm:667: In file included from /usr/bin/../include/c++/v1/functional:506: In file included from /usr/bin/../include/c++/v1/__functional/function.h:22: In file included from /usr/bin/../include/c++/v1/__memory/shared_ptr.h:35: In file included from /usr/bin/../include/c++/v1/atomic:524: In file included from /usr/bin/../include/c++/v1/__thread/timed_backoff_policy.h:16: /usr/bin/../include/c++/v1/__threading_support:260:14: error: use of undeclared identifier 'pthread_mutexattr_init'; did you mean 'pthread_mutexattr_t'? int __ec = pthread_mutexattr_init(&attr); ^ /usr/riscv64-elf/include/sys/_pthreadtypes.h:169:3: note: 'pthread_mutexattr_t' declared here } pthread_mutexattr_t; ^ So here it seems like libc++ and newlib are not compatible. Without newlib it boils down to only two: In file included from takes_string_view.cpp:2: In file included from /usr/bin/../include/c++/v1/string_view:205: In file included from /usr/bin/../include/c++/v1/__string:13: In file included from /usr/bin/../include/c++/v1/__algorithm/copy.h:12: In file included from /usr/bin/../include/c++/v1/__algorithm/unwrap_iter.h:14: In file included from /usr/bin/../include/c++/v1/iterator:587: In file included from /usr/bin/../include/c++/v1/__functional_base:25: /usr/bin/../include/c++/v1/typeinfo:246:14: error: cast from pointer to smaller type 'std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__type_name_t' (aka 'unsigned int') loses information return reinterpret_cast<__type_name_t>(__v); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from takes_string_view.cpp:2: In file included from /usr/bin/../include/c++/v1/string_view:206: In file included from /usr/bin/../include/c++/v1/algorithm:759: /usr/bin/../include/c++/v1/__algorithm/shuffle.h:57:12: error: cast from pointer to smaller type 'uintptr_t' (aka 'unsigned int') loses information return reinterpret_cast<uintptr_t>(&__x); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Still unexpected, but maybe they could be hacked around. In any event, you should check if libstdc++ supports newlib underneath. Those GNU projects tend to be tied together. We can CC the maintainers for libstdc++ if you want.