Description
When trying to use libc++ with LLVM libc on a baremetal platform, we encountered an issue with the __using_if_exists__
attribute which was introduced in https://reviews.llvm.org/D90188:
In file included from /llvm_libcxx/include/algorithm:1973:
/llvm_libcxx/include/__algorithm/remove.h:28:1: error: declaration conflicts with target of using declaration already in scope
28 | remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
| ^
/llvm_libcxx/include/cstdio:155:1: note: target of using declaration
155 | using ::remove _LIBCPP_USING_IF_EXISTS;
| ^
/llvm_libcxx/include/cstdio:155:9: note: using declaration
155 | using ::remove _LIBCPP_USING_IF_EXISTS;
| ^
This is because baremetal version of the stdio.h
libc header doesn't include remove
(since there's no filesystem support).
A more minimal example of this issue is:
void foo();
namespace N {
void bar();
using ::foo __attribute__((__using_if_exists__));
using ::bar __attribute__((__using_if_exists__));
}
void baz() {
N::bar();
}
This results in the following error (you can also see it at https://godbolt.org/z/dTxqnc1oP):
<source>:7:11: error: target of using declaration conflicts with declaration already in scope
7 | using ::bar __attribute__((__using_if_exists__));
| ^
<source>:7:3: note: target of using declaration
7 | using ::bar __attribute__((__using_if_exists__));
| ^
<source>:4:8: note: conflicting declaration
4 | void bar();
| ^
1 error generated.
Compiler returned: 1
Normally, remove
is declared in stdio.h
, which corresponds to the foo
case.
In our case, there's no remove
symbol in stdio.h
and as such there's no such symbol in the global namespace, but there's remove
in the std::
namespace introduced by algorithm
corresponding to the bar
case.
Is this an issue with the __using_if_exists__
implementation or intended behavior?
This is related to issue #84879.