Richard Earnshaw <richard.earns...@foss.arm.com> writes: > On 03/10/2023 16:18, Victor Do Nascimento wrote: >> In implementing the ACLE read/write system register builtins it was >> observed that leaving argument type checking to be done at expand-time >> meant that poorly-formed function calls were being "fixed" by certain >> optimization passes, meaning bad code wasn't being properly picked up >> in checking. >> >> Example: >> >> const char *regname = "amcgcr_el0"; >> long long a = __builtin_aarch64_rsr64 (regname); >> >> is reduced by the ccp1 pass to >> >> long long a = __builtin_aarch64_rsr64 ("amcgcr_el0"); >> >> As these functions require an argument of STRING_CST type, there needs >> to be a check carried out by the front-end capable of picking this up. >> >> The introduced `check_general_builtin_call' function will be called by >> the TARGET_CHECK_BUILTIN_CALL hook whenever a call to a builtin >> belonging to the AARCH64_BUILTIN_GENERAL category is encountered, >> carrying out any appropriate checks associated with a particular >> builtin function code. > > Doesn't this prevent reasonable wrapping of the __builtin... names with > something more palatable? Eg: > > static inline __attribute__(("always_inline")) long long get_sysreg_ll > (const char *regname) > { > return __builtin_aarch64_rsr64 (regname); > } > > ... > long long x = get_sysreg_ll("amcgcr_el0"); > ...
I think it's case of picking your poison. If we didn't do this, and only checked later, then it's unlikely that GCC and Clang would be consistent about when a constant gets folded soon enough. But yeah, it means that the above would need to be a macro in C. Enlightened souls using C++ could instead do: template<const char *regname> long long get_sysreg_ll() { return __builtin_aarch64_rsr64(regname); } ... get_sysreg_ll<"amcgcr_el0">() ... Or at least I hope so. Might be nice to have a test for this. Thanks, Richard