Comment # 7 on bug 1199943 from
(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.


You are receiving this mail because: