[Bug]: Unable to disable a builtin with -fno-builtin-wmemchr
Yavnikaa opened this issue · 17 comments
Description
Hi
I want to disable certain wchar_t related builtins in my build environment. However, even after using the flag -fno-builtin- as mentioned in the LLVM documentation, the code is still not executing as desired. Attaching a small repro:
https://godbolt.org/z/K87YaW3ee
I am using NDK r27 stable release, and Clang 18 packaged with it. My goal is to disable the builtins being used in the header. Any other method to configure the builtins?
Upstream bug
No response
Commit to cherry-pick
No response
Affected versions
r26, r27
Canary version
No response
Host OS
Windows
Host OS version
Windows11
Affected ABIs
armeabi-v7a, arm64-v8a, x86, x86_64
-fno-builtin-foo
doesn't remove __builtin_foo
, it just makes the compiler not replace invocations of foo
with its builtin versions. GCC has the same behavior: https://gcc.godbolt.org/z/neP651GK7
Got it, thanks!
So is there anyway to not use builtins at all? In my build environment, wchar_t is of 2 bytes, as opposed to the NDK's 4 bytes and therefore I can't use builtins as such. Given that there's a check __has_builtin, I was wondering if there's anyway to disable builtins completely.
In my build environment, wchar_t is of 2 bytes, as opposed to the NDK's 4 bytes
... what are you doing? This sounds very much like an X/Y problem.
That's not the concern as such. I was just giving the context for why I need to disable builtins_w*.
Can you please guide me on how can we disable builtins_w* across the NDK?
Won't that disable all builtins? I only want to disable specific ones. And as per the previous snippet shared here by @jmgao , I doubt if -fno-builtin will abstain the compiler from using builtins.
Seems like other builtins aren't getting disabled either at optimization levels like -O2 https://godbolt.org/z/n55b366sK
But what are you expecting to happen after they're disabled? The libc headers use those builtins directly. If you disable them, won't your code just fail to compile?
That's why I'm trying to figure out why you need this. I don't think we can do what you're asking for, but it sounds like you're asking for a workaround instead of a fix, and I'd like to help you with a fix instead of the workaround that we likely cannot provide.
Sharing a snippet from NDK R27 RC1, defining constexpr_wmemchr. There's a fallback here when the __has_builtin check returns false, and hence the compilation would be successful.
Yes, it might seem like a workaround but my build environment is cross-plat and we have been using 2 byte wchar_t. We have overridden wrappers to consume the NDK with our specifications. Since __builtins are intrinsic, we are facing difficulty in using builtins_w*. Thus the best solution for now seems to disable these builtins being used in the cwchar header. Any help would be greatly appreciated, thanks!
If I understand correctly, you're asking me to go ask LLVM to change the behavior of -fno-builtin
to also disable all __builtin_*
. I can't do that if I don't understand the problem. You're asking for the compiler to help you build ABI-incompatible code, and without knowing why you need it, I don't know how to make your case. Are you using wchar_t
for UTF-16, and are trying to avoid rewriting that with char16_t
? If not, what's the problem?
Alternatively, you can go ask LLVM directly.
i suspect they have a bunch of Windows code that assumes wchar_t
is 2 bytes rather than 4. they're probably trying to use -fshort-wchar
to ignore that, not realizing that the trade off is "the non-standard ABI you just selected is incompatible with libc/libc++".
i think the usual "least worst" option to dig your way out of this particular portability pain is to s/wchar_t/WCHAR16/ or whatever in the affected areas, then #define WCHAR16
to something appropriate for each platform.
i don't think anyone's ever found a silver bullet in the 30 years of "Windows is different from everyone else" we've had up to now.
Right, that'd be the "rewrite with char16_t
" I was talking about (and whatever plumbing you need to do that).
@enh-google yes I agree with you but we have a lot of cross-platform legacy code and can't really change all the instances. Yes we are using -fshort-wchar.
@DanAlbert I am really sorry but I interpreted -fno-builtin as being able to disable builtins rather than its actual behaviour as elucidated here above by @jmgao . I am just confirming now if there is any way at all for me to disable the builtins used in the cwchar header. If there isn't any standard way to do it, I understand and then we can close the bug.
Eventually we are planning to shift to char16_t, and would aim to align with the ABI. Thankyou for your patience and help!
I am just confirming now if there is any way at all for me to disable the builtins used in the cwchar header.
No, there isn't. Unfortunately you will need to port your code to Android.
(note that specifically <cwchar>
is a libc++ header ... you might have a less bad time with <wchar.h>
instead?)
Huh, usually there's no difference between the two in libc++, but it looks like there is for that one https://github.com/llvm/llvm-project/blob/main/libcxx/include/wchar.h (and maybe they've started doing things differently and that's more broadly true)
Huh, usually there's no difference between the two in libc++,
(there are all kinds of random subtelties -- and obviously zero guarantees -- which is why in code review i always make people use <foo.h>
instead of <cfoo>
unless they can explain to me how the two differ, and what specifically they need from the <cfoo>
variant.)