Passing constrained enums via ...: should they be zero-extended to register size?

6 views
Skip to first unread message

Thiago Macieira

unread,
Apr 30, 2020, 10:56:09 PM4/30/20
to IA32 System V Application Binary Interface
Code:
#include <stdio.h>

enum E1 {};
enum E2 : unsigned char {};
enum class E3 : unsigned char {};

void f(E1 e) { printf("%d", e); }
void f(E2 e) { printf("%d", e); }
void f(E3 e) { printf("%d", e); }

Godbolt: https://gcc.godbolt.org/z/48QXdJ
Note: Clang's warning on the third `f` is the crux of this problem.

Note how GCC zero-extends for `E2` and ICC zero-extends for `E2` and `E3`, but
Clang does for neither. (MSVC is there just because I had it open anyway)

Should enum arguments when passed via `...` be zero extended?

How about when not passing through `...`? See https://gcc.godbolt.org/z/vLMfaX
where GCC zero-extends the same way but now ICC does not.

This may not be a bug anywhere if the ABI specifies that the only the low 8-
bits are valid. In fact, if you add another overload with "unsigned char" as a
parameter, GCC does zero-extend but Clang doesn't. But I can't find that
wording in the document talking about zeror-extending or type promotion to
int.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel System Software Products



H.J. Lu

unread,
May 3, 2020, 11:03:14 AM5/3/20
to IA32 System V Application Binary Interface
On Thu, Apr 30, 2020 at 7:56 PM Thiago Macieira <thi...@macieira.org> wrote:
>
> Code:
> #include <stdio.h>
>
> enum E1 {};
> enum E2 : unsigned char {};
> enum class E3 : unsigned char {};
>
> void f(E1 e) { printf("%d", e); }
> void f(E2 e) { printf("%d", e); }
> void f(E3 e) { printf("%d", e); }
>
> Godbolt: https://gcc.godbolt.org/z/48QXdJ
> Note: Clang's warning on the third `f` is the crux of this problem.
>
> Note how GCC zero-extends for `E2` and ICC zero-extends for `E2` and `E3`, but
> Clang does for neither. (MSVC is there just because I had it open anyway)
>
> Should enum arguments when passed via `...` be zero extended?
>
> How about when not passing through `...`? See https://gcc.godbolt.org/z/vLMfaX
> where GCC zero-extends the same way but now ICC does not.
>
> This may not be a bug anywhere if the ABI specifies that the only the low 8-
> bits are valid. In fact, if you add another overload with "unsigned char" as a
> parameter, GCC does zero-extend but Clang doesn't. But I can't find that
> wording in the document talking about zeror-extending or type promotion to
> int.
>

Here is a related function on function return value:

https://groups.google.com/forum/#!topic/ia32-abi/9H4BBrIdkmk

The upper bits are undefined when passing a 8-bit value.

--
H.J.
Reply all
Reply to author
Forward
0 new messages