You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
voidfoo();
namespaceN {
voidbar();
using ::foo __attribute__((__using_if_exists__));
using ::bar __attribute__((__using_if_exists__));
}
voidbaz() {
N::bar();
}
<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?
Thanks for filing this issue! I've come across this several times on various platforms and I believe this is a Clang bug in the way it implements the attribute. Basically the intent is that if there is no ::bar declaration, the using ::bar __attribute__((using_if_exists)); declaration shouldn't declare anything. But the way this is implemented in Clang IIRC is that we actually do create a special kind of declaration representing "no declaration at all". And then that conflicts with the existing declaration for N::bar.
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:This is because baremetal version of the
stdio.h
libc header doesn't includeremove
(since there's no filesystem support).A more minimal example of this issue is:
This results in the following error (you can also see it at https://godbolt.org/z/dTxqnc1oP):
Normally,
remove
is declared instdio.h
, which corresponds to thefoo
case.In our case, there's no
remove
symbol instdio.h
and as such there's no such symbol in the global namespace, but there'sremove
in thestd::
namespace introduced byalgorithm
corresponding to thebar
case.Is this an issue with the
__using_if_exists__
implementation or intended behavior?This is related to issue #84879.
CC @ldionne @zygoloid @AaronBallman @epilk
The text was updated successfully, but these errors were encountered: