From 9f31df34d91fcac7c82af842678ffae2749f0bdf Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Mon, 1 Apr 2024 12:20:28 -0700 Subject: [PATCH] Attribute: do not apply vector_size to enums clang silently ignores the attribute; GCC issues an error diagnostic Fixes #658 --- src/aro/Attribute.zig | 10 ++++--- test/cases/ast/vectors.c | 3 --- test/cases/enum attributes clang.c | 42 ++++++++++++++++++++++++++++++ test/cases/enum attributes gcc.c | 8 ++++++ test/cases/enum attributes.c | 34 ------------------------ 5 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 test/cases/enum attributes clang.c create mode 100644 test/cases/enum attributes gcc.c delete mode 100644 test/cases/enum attributes.c diff --git a/src/aro/Attribute.zig b/src/aro/Attribute.zig index c5065a90..0c1f1e0d 100644 --- a/src/aro/Attribute.zig +++ b/src/aro/Attribute.zig @@ -1049,11 +1049,13 @@ fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type) } fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void { - if (!(ty.isInt() or ty.isFloat()) or !ty.isReal()) { - const orig_ty = try p.typeStr(ty.*); - ty.* = Type.invalid; - return p.errStr(.invalid_vec_elem_ty, tok, orig_ty); + const is_enum = ty.is(.@"enum"); + if (!(ty.isInt() or ty.isFloat()) or !ty.isReal() or (is_enum and p.comp.langopts.emulate == .gcc)) { + try p.errStr(.invalid_vec_elem_ty, tok, try p.typeStr(ty.*)); + return error.ParsingFailed; } + if (is_enum) return; + const vec_bytes = attr.args.vector_size.bytes; const ty_size = ty.sizeof(p.comp).?; if (vec_bytes % ty_size != 0) { diff --git a/test/cases/ast/vectors.c b/test/cases/ast/vectors.c index d6ff1127..508e1416 100644 --- a/test/cases/ast/vectors.c +++ b/test/cases/ast/vectors.c @@ -1,6 +1,3 @@ -typedef: 'invalid' - name: invalid1 - typedef: 'float' name: invalid2 diff --git a/test/cases/enum attributes clang.c b/test/cases/enum attributes clang.c new file mode 100644 index 00000000..bb88d320 --- /dev/null +++ b/test/cases/enum attributes clang.c @@ -0,0 +1,42 @@ +//aro-args --emulate=clang +enum E { + is_deprecated __attribute__((deprecated)), + is_deprecated_with_msg __attribute__((deprecated("I am deprecated"))), + is_unavailable __attribute__((unavailable)), + is_unavailable_with_msg __attribute__((unavailable("I am not available"))), + newval, +}; + +void foo(void) { + int a = newval; + a = is_deprecated; + a = is_deprecated_with_msg; + a = is_unavailable; + a = is_unavailable_with_msg; +} + +enum __attribute__((aligned(16))) Attributed { + Val, +}; +_Static_assert(_Alignof(enum Attributed) == 16, "enum align"); + +enum Trailing { + Foo +} __attribute__((aligned(32))); +_Static_assert(_Alignof(enum Trailing) == 32, "enum align"); + +enum __attribute__((vector_size(32))) VectorSize1; + +enum __attribute__((vector_size(32))) VectorSize2 { + A +}; + + +#define EXPECTED_ERRORS "enum attributes clang.c:12:7: warning: 'is_deprecated' is deprecated [-Wdeprecated-declarations]" \ + "enum attributes clang.c:3:33: note: 'is_deprecated' has been explicitly marked deprecated here" \ + "enum attributes clang.c:13:7: warning: 'is_deprecated_with_msg' is deprecated: I am deprecated [-Wdeprecated-declarations]" \ + "enum attributes clang.c:4:42: note: 'is_deprecated_with_msg' has been explicitly marked deprecated here" \ + "enum attributes clang.c:14:7: error: 'is_unavailable' is unavailable" \ + "enum attributes clang.c:5:34: note: 'is_unavailable' has been explicitly marked unavailable here" \ + "enum attributes clang.c:15:7: error: 'is_unavailable_with_msg' is unavailable: I am not available" \ + "enum attributes clang.c:6:44: note: 'is_unavailable_with_msg' has been explicitly marked unavailable here" \ diff --git a/test/cases/enum attributes gcc.c b/test/cases/enum attributes gcc.c new file mode 100644 index 00000000..5885b66e --- /dev/null +++ b/test/cases/enum attributes gcc.c @@ -0,0 +1,8 @@ +//aro-args --emulate=gcc + +enum __attribute__((vector_size(32))) VectorSize2 { + A +}; + +#define EXPECTED_ERRORS "enum attributes gcc.c:3:21: error: invalid vector element type 'enum VectorSize2'" \ + diff --git a/test/cases/enum attributes.c b/test/cases/enum attributes.c deleted file mode 100644 index cffb6bf3..00000000 --- a/test/cases/enum attributes.c +++ /dev/null @@ -1,34 +0,0 @@ -enum E { - is_deprecated __attribute__((deprecated)), - is_deprecated_with_msg __attribute__((deprecated("I am deprecated"))), - is_unavailable __attribute__((unavailable)), - is_unavailable_with_msg __attribute__((unavailable("I am not available"))), - newval, -}; - -void foo(void) { - int a = newval; - a = is_deprecated; - a = is_deprecated_with_msg; - a = is_unavailable; - a = is_unavailable_with_msg; -} - -enum __attribute__((aligned(16))) Attributed { - Val, -}; -_Static_assert(_Alignof(enum Attributed) == 16, "enum align"); - -enum Trailing { - Foo -} __attribute__((aligned(32))); -_Static_assert(_Alignof(enum Trailing) == 32, "enum align"); - -#define EXPECTED_ERRORS "enum attributes.c:11:7: warning: 'is_deprecated' is deprecated [-Wdeprecated-declarations]" \ - "enum attributes.c:2:33: note: 'is_deprecated' has been explicitly marked deprecated here" \ - "enum attributes.c:12:7: warning: 'is_deprecated_with_msg' is deprecated: I am deprecated [-Wdeprecated-declarations]" \ - "enum attributes.c:3:42: note: 'is_deprecated_with_msg' has been explicitly marked deprecated here" \ - "enum attributes.c:13:7: error: 'is_unavailable' is unavailable" \ - "enum attributes.c:4:34: note: 'is_unavailable' has been explicitly marked unavailable here" \ - "enum attributes.c:14:7: error: 'is_unavailable_with_msg' is unavailable: I am not available" \ - "enum attributes.c:5:44: note: 'is_unavailable_with_msg' has been explicitly marked unavailable here" \