PR c/88383 - ICE calling __builtin_has_attribute on a reference
PR c/88383 - ICE calling __builtin_has_attribute on a reference PR c/89288 - ICE in tree_code_size, at tree.c:865 PR c/89798 - excessive vector_size silently accepted and truncated PR c/89797 - ICE on a vector_size (1LU << 33) int variable gcc/ChangeLog: PR c/89797 * targhooks.c (default_vector_alignment): Avoid assuming argument fits in SHWI. * tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in a shift expression. * doc/extend.texi (__builtin_has_attribute): Add a clarifying note. gcc/c-family/ChangeLog: PR c/88383 PR c/89288 PR c/89798 PR c/89797 * c-attribs.c (type_valid_for_vector_size): Detect excessively large sizes. (validate_attribute): Handle DECLs and expressions. (has_attribute): Handle types referenced by expressions. Avoid considering array attributes in ARRAY_REF expressions . gcc/cp/ChangeLog: PR c/88383 PR c/89288 * parser.c (cp_parser_has_attribute_expression): Handle assignment expressions. gcc/testsuite/ChangeLog: PR c/88383 PR c/89288 PR c/89798 PR c/89797 * c-c++-common/attributes-1.c: Adjust. * c-c++-common/builtin-has-attribute-6.c: New test. * c-c++-common/builtin-has-attribute-7.c: New test. * c-c++-common/builtin-has-attribute-4.c: Adjust expectations. * c-c++-common/builtin-has-attribute-6.c: New test. * c-c++-common/pr71574.c: Adjust. * gcc.dg/pr25559.c: Adjust. * gcc.dg/attr-vector_size.c: New test. From-SVN: r270326
This commit is contained in:
parent
3d8695f529
commit
3fb82380dc
13 changed files with 692 additions and 19 deletions
|
@ -1,5 +1,17 @@
|
|||
2019-04-12 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/88383
|
||||
PR c/89288
|
||||
PR c/89798
|
||||
PR c/89797
|
||||
* targhooks.c (default_vector_alignment): Avoid assuming
|
||||
argument fits in SHWI.
|
||||
* tree.h (TYPE_VECTOR_SUBPARTS): Avoid sign overflow in
|
||||
a shift expression.
|
||||
* doc/extend.texi (__builtin_has_attribute): Add a clarifying note.
|
||||
|
||||
2019-04-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
|
||||
PR rtl-optimization/89965
|
||||
* dce.c: Include rtl-iter.h.
|
||||
(struct check_argument_load_data): New type.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2019-04-12 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/88383
|
||||
PR c/89288
|
||||
* parser.c (cp_parser_has_attribute_expression): Handle assignment
|
||||
expressions.
|
||||
|
||||
2019-04-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* call.c (null_member_pointer_value_p): Handle an empty CONSTRUCTOR
|
||||
|
|
|
@ -8555,9 +8555,9 @@ cp_parser_has_attribute_expression (cp_parser *parser)
|
|||
cp_parser_parse_definitely (parser);
|
||||
|
||||
/* If the type-id production did not work out, then we must be
|
||||
looking at the unary-expression production. */
|
||||
looking at an expression. */
|
||||
if (!oper || oper == error_mark_node)
|
||||
oper = cp_parser_unary_expression (parser);
|
||||
oper = cp_parser_assignment_expression (parser);
|
||||
|
||||
STRIP_ANY_LOCATION_WRAPPER (oper);
|
||||
|
||||
|
|
|
@ -1247,14 +1247,18 @@ constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align)
|
|||
return align;
|
||||
}
|
||||
|
||||
/* Default to natural alignment for vector types. */
|
||||
/* Default to natural alignment for vector types, bounded by
|
||||
MAX_OFILE_ALIGNMENT. */
|
||||
|
||||
HOST_WIDE_INT
|
||||
default_vector_alignment (const_tree type)
|
||||
{
|
||||
HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type));
|
||||
if (align > MAX_OFILE_ALIGNMENT)
|
||||
align = MAX_OFILE_ALIGNMENT;
|
||||
return align;
|
||||
unsigned HOST_WIDE_INT align = MAX_OFILE_ALIGNMENT;
|
||||
tree size = TYPE_SIZE (type);
|
||||
if (tree_fits_uhwi_p (size))
|
||||
align = tree_to_uhwi (size);
|
||||
|
||||
return align < MAX_OFILE_ALIGNMENT ? align : MAX_OFILE_ALIGNMENT;
|
||||
}
|
||||
|
||||
/* The default implementation of
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
2019-04-12 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/88383
|
||||
PR c/89288
|
||||
PR c/89798
|
||||
PR c/89797
|
||||
* c-c++-common/attributes-1.c: Adjust.
|
||||
* c-c++-common/builtin-has-attribute-4.c: Adjust expectations.
|
||||
* c-c++-common/builtin-has-attribute-6.c: New test.
|
||||
* c-c++-common/builtin-has-attribute-7.c: New test.
|
||||
* c-c++-common/pr71574.c: Adjust.
|
||||
* gcc.dg/pr25559.c: Adjust.
|
||||
* gcc.dg/attr-vector_size.c: New test.
|
||||
|
||||
2019-04-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
|
||||
PR rtl-optimization/89965
|
||||
* gcc.target/i386/pr89965.c: New test.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(1,bar))); /* { dg-warning ".alloc_size. attribute argument 2 is invalid" } */
|
||||
void* my_realloc(void*, unsigned) __attribute__((alloc_size(bar))); /* { dg-warning ".alloc_size. attribute argument is invalid" } */
|
||||
|
||||
typedef char vec __attribute__((vector_size(bar))); /* { dg-warning "ignored" } */
|
||||
typedef char vec __attribute__((vector_size(bar)));
|
||||
|
||||
void f1(char*) __attribute__((nonnull(bar))); /* { dg-warning ".nonnull. attribute argument is invalid" } */
|
||||
|
||||
|
@ -14,7 +14,7 @@ void foo(int);
|
|||
void* my_calloc(unsigned, unsigned) __attribute__((alloc_size(1,foo))); /* { dg-warning ".alloc_size. attribute argument 2 has type .void\\\(int\\\)." } */
|
||||
void* my_realloc(void*, unsigned) __attribute__((alloc_size(foo))); /* { dg-warning ".alloc_size. attribute argument has type .void ?\\\(int\\\)" } */
|
||||
|
||||
typedef char vec __attribute__((vector_size(foo))); /* { dg-warning "ignored" } */
|
||||
typedef char vec __attribute__((vector_size(foo))); /* { dg-error ".vector_size. attribute argument value .foo. is not an integer constant" } */
|
||||
|
||||
void f1(char*) __attribute__((nonnull(foo))); /* { dg-warning ".nonnull. attribute argument has type .void ?\\\(int\\\)." } */
|
||||
void f2(char*) __attribute__((nonnull(1,foo))); /* { dg-warning ".nonnull. attribute argument 2 has type .void ?\\\(int\\\)." } */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{ dg-skip-if "No section attribute" { { hppa*-*-hpux* } && { ! lp64 } } }
|
||||
{ dg-options "-Wall -ftrack-macro-expansion=0" }
|
||||
{ dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } }
|
||||
{ dg-additional-options "-DSKIP_ALIAS" { target *-*-darwin* } }
|
||||
{ dg-additional-options "-DSKIP_ALIAS" { target *-*-darwin* } }
|
||||
*/
|
||||
|
||||
#define ATTR(...) __attribute__ ((__VA_ARGS__))
|
||||
|
@ -155,7 +155,8 @@ void test_packed (struct PackedMember *p)
|
|||
A (0, gpak[0].c, packed);
|
||||
A (0, gpak[1].s, packed);
|
||||
A (1, gpak->a, packed);
|
||||
A (1, (*gpak).a[0], packed);
|
||||
/* It's the array that's declared packed but not its elements. */
|
||||
A (0, (*gpak).a[0], packed);
|
||||
|
||||
/* The following fails because in C it's represented as
|
||||
INDIRECT_REF (POINTER_PLUS (NOP_EXPR (ADDR_EXPR (gpak)), ...))
|
||||
|
@ -165,7 +166,8 @@ void test_packed (struct PackedMember *p)
|
|||
A (0, p->c, packed);
|
||||
A (0, p->s, packed);
|
||||
A (1, p->a, packed);
|
||||
A (1, p->a[0], packed);
|
||||
/* It's the array that's declared packed but not its elements. */
|
||||
A (0, p->a[0], packed);
|
||||
/* Similar to the comment above.
|
||||
A (1, *p->a, packed); */
|
||||
}
|
||||
|
@ -218,13 +220,68 @@ void test_vector_size (void)
|
|||
A (1, iv16, vector_size (16));
|
||||
A (0, iv16, vector_size (32));
|
||||
|
||||
/* Verify that the attribute not detected on an array of vectors
|
||||
but is detected on its elements. */
|
||||
typedef ATTR (vector_size (8)) float afv8_t[4];
|
||||
A (0, afv8_t, vector_size);
|
||||
A (0, afv8_t, vector_size (1));
|
||||
A (0, afv8_t, vector_size (2));
|
||||
A (0, afv8_t, vector_size (4));
|
||||
A (0, afv8_t, vector_size (8));
|
||||
A (0, afv8_t, vector_size (16));
|
||||
|
||||
A (1, __typeof__ ((*(afv8_t*)0)[0]), vector_size);
|
||||
A (0, __typeof__ ((*(afv8_t*)0)[1]), vector_size (1));
|
||||
A (0, __typeof__ ((*(afv8_t*)0)[2]), vector_size (2));
|
||||
A (0, __typeof__ ((*(afv8_t*)0)[3]), vector_size (4));
|
||||
A (1, __typeof__ ((*(afv8_t*)0)[0]), vector_size (8));
|
||||
A (0, __typeof__ ((*(afv8_t*)0)[1]), vector_size (16));
|
||||
|
||||
A (1, __typeof__ (**(afv8_t*)0), vector_size);
|
||||
A (0, __typeof__ (**(afv8_t*)0), vector_size (1));
|
||||
A (0, __typeof__ (**(afv8_t*)0), vector_size (2));
|
||||
A (0, __typeof__ (**(afv8_t*)0), vector_size (4));
|
||||
A (1, __typeof__ (**(afv8_t*)0), vector_size (8));
|
||||
A (0, __typeof__ (**(afv8_t*)0), vector_size (16));
|
||||
|
||||
ATTR (vector_size (8)) float afv8[4];
|
||||
A (1, afv8, vector_size);
|
||||
A (0, afv8, vector_size);
|
||||
A (0, afv8, vector_size (1));
|
||||
A (0, afv8, vector_size (2));
|
||||
A (0, afv8, vector_size (4));
|
||||
A (1, afv8, vector_size (8));
|
||||
A (0, afv8, vector_size (8));
|
||||
A (0, afv8, vector_size (16));
|
||||
|
||||
A (1, afv8[0], vector_size);
|
||||
A (0, afv8[1], vector_size (1));
|
||||
A (0, afv8[2], vector_size (2));
|
||||
A (0, afv8[3], vector_size (4));
|
||||
A (1, afv8[0], vector_size (8));
|
||||
A (0, afv8[1], vector_size (16));
|
||||
|
||||
A (1, *afv8, vector_size);
|
||||
A (0, *afv8, vector_size (1));
|
||||
A (0, *afv8, vector_size (2));
|
||||
A (0, *afv8, vector_size (4));
|
||||
A (1, *afv8, vector_size (8));
|
||||
A (0, *afv8, vector_size (16));
|
||||
|
||||
/* sizeof (long double) is 12 on i386. */
|
||||
enum { VecSize = 8 * sizeof (long double) };
|
||||
ATTR (vector_size (VecSize)) long double aldv[1][2][3];
|
||||
A (0, aldv, vector_size);
|
||||
A (0, aldv[0], vector_size);
|
||||
A (0, aldv[0][0], vector_size);
|
||||
A (1, aldv[0][0][0], vector_size);
|
||||
A (0, aldv[0][0][1], vector_size (VecSize / 2));
|
||||
A (1, aldv[0][0][2], vector_size (VecSize));
|
||||
|
||||
A (0, aldv[0][0][0][0], vector_size);
|
||||
|
||||
A (0, *aldv, vector_size);
|
||||
A (0, **aldv, vector_size);
|
||||
A (1, ***aldv, vector_size);
|
||||
A (1, ***aldv, vector_size (VecSize));
|
||||
}
|
||||
|
||||
|
||||
|
|
114
gcc/testsuite/c-c++-common/builtin-has-attribute-6.c
Normal file
114
gcc/testsuite/c-c++-common/builtin-has-attribute-6.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* PR c/88383 - ICE calling _builtin_has_attribute(r, aligned(N)))
|
||||
on an overaligned reference r
|
||||
PR c/89288 - ICE in tree_code_size, at tree.c:865
|
||||
{ dg-options "-Wall -ftrack-macro-expansion=0" }
|
||||
{ dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } } */
|
||||
|
||||
#define ATTR(...) __attribute__ ((__VA_ARGS__))
|
||||
|
||||
#define A(expect, sym, attr) \
|
||||
typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
|
||||
|
||||
typedef ATTR (aligned (8)) int Int8;
|
||||
|
||||
/* The attribute applies to the array, not to the type of its elements. */
|
||||
extern ATTR (aligned (8)) char i8arr[];
|
||||
|
||||
/* The attribute applies to the pointer, not to the type it points to. */
|
||||
extern ATTR (aligned (8)) int *ptr;
|
||||
extern Int8 *i8ptr;
|
||||
|
||||
#if __cplusplus
|
||||
|
||||
/* Similarly here, the attribute applies to the reference, not to its type. */
|
||||
extern ATTR (aligned (8)) int &ref;
|
||||
extern Int8 &i8ref;
|
||||
|
||||
#else
|
||||
|
||||
/* Fake references in C. */
|
||||
extern ATTR (aligned (8)) int ref;
|
||||
Int8 i8ref;
|
||||
|
||||
#endif
|
||||
|
||||
void test (void)
|
||||
{
|
||||
/* Verify that the built-in detects the attribute on the array. */
|
||||
A (1, i8arr, aligned);
|
||||
A (0, i8arr, aligned (1));
|
||||
A (0, i8arr, aligned (2));
|
||||
A (0, i8arr, aligned (4));
|
||||
A (1, i8arr, aligned (8));
|
||||
A (0, i8arr, aligned (16));
|
||||
|
||||
A (0, i8arr + 1, aligned);
|
||||
A (0, i8arr + 2, aligned (1));
|
||||
A (0, i8arr + 3, aligned (8));
|
||||
|
||||
/* Verify the builtin detects the absence of the attribute on
|
||||
the elements. */
|
||||
A (0, i8arr[0], aligned);
|
||||
A (0, *i8arr, aligned);
|
||||
|
||||
/* Verify that the built-in doesn't confuse the attribute on
|
||||
the pointer type with that to the pointed to type. This
|
||||
also exercises PR c/89288. */
|
||||
A (0, (Int8*)0, aligned);
|
||||
A (0, (int*)0, aligned);
|
||||
A (0, (void*)0, aligned);
|
||||
A (0, 0, aligned);
|
||||
|
||||
/* Verify that the built-in detects the attribute on the pointer
|
||||
itself. */
|
||||
A (1, ptr, aligned);
|
||||
A (0, ptr, aligned (1));
|
||||
A (0, ptr, aligned (2));
|
||||
A (0, ptr, aligned (4));
|
||||
A (1, ptr, aligned (8));
|
||||
A (0, ptr, aligned (16));
|
||||
|
||||
A (0, ptr + 1, aligned);
|
||||
A (0, ptr + 2, aligned (1));
|
||||
A (0, ptr + 3, aligned (8));
|
||||
|
||||
/* The pointed to type is not declared with attribute aligned. */
|
||||
A (0, *ptr, aligned);
|
||||
A (0, *ptr, aligned (1));
|
||||
A (0, *ptr, aligned (2));
|
||||
A (0, *ptr, aligned (4));
|
||||
A (0, *ptr, aligned (8));
|
||||
A (0, *ptr, aligned (16));
|
||||
|
||||
A (0, *ptr + 1, aligned);
|
||||
A (0, *ptr + 2, aligned (1));
|
||||
A (0, *ptr + 3, aligned (8));
|
||||
|
||||
/* Verify that the built-in correctly detects the attribute on
|
||||
the type of the lvalue referenced by the pointer. */
|
||||
A (0, i8ptr, aligned);
|
||||
A (0, i8ptr, aligned (8));
|
||||
A (0, i8ptr + 1, aligned);
|
||||
A (0, i8ptr + 3, aligned (8));
|
||||
A (1, *i8ptr, aligned);
|
||||
A (0, *i8ptr, aligned (1));
|
||||
A (0, *i8ptr, aligned (2));
|
||||
A (0, *i8ptr, aligned (4));
|
||||
A (1, *i8ptr, aligned (8));
|
||||
A (0, *i8ptr, aligned (16));
|
||||
|
||||
/* The reference itself is declared aligned, even though the type
|
||||
it refers to isn't. But see PR c++/88362. */
|
||||
A (1, ref, aligned);
|
||||
A (0, ref, aligned (1));
|
||||
A (0, ref, aligned (2));
|
||||
A (0, ref, aligned (4));
|
||||
A (1, ref, aligned (8));
|
||||
A (0, ref, aligned (16));
|
||||
|
||||
/* Also verify that assignment expressions are accepted. */
|
||||
A (0, ref = 1, aligned);
|
||||
A (0, ref += 2, aligned (1));
|
||||
A (0, ref /= 3, aligned (8));
|
||||
|
||||
}
|
396
gcc/testsuite/c-c++-common/builtin-has-attribute-7.c
Normal file
396
gcc/testsuite/c-c++-common/builtin-has-attribute-7.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/* Verify that __builtin_has_attribute detects attributes aligned
|
||||
and packed in various forms of array dereferencing and indirection
|
||||
expressions correspondingly to __alignof__.
|
||||
{ dg-do compile }
|
||||
{ dg-options "-Wall -Wno-unused -ftrack-macro-expansion=0" } */
|
||||
|
||||
#define ATTR(...) __attribute__ ((__VA_ARGS__))
|
||||
#define ALIGN(N) ATTR (aligned (N))
|
||||
|
||||
#define Assert(expr) typedef int _Assert [1 - 2 * !(expr)]
|
||||
|
||||
/* Verify that __builtin_has_attribute (EXPR, align (ALIGN)) returns
|
||||
the EXPECTed result. When EXPECT is true, verify that the EXPression
|
||||
has the expected ALIGNment. */
|
||||
#define A3(expect, expr, align) do { \
|
||||
Assert (!expect || __alignof__ (expr) == align); \
|
||||
Assert (expect == __builtin_has_attribute (expr, aligned (align))); \
|
||||
} while (0)
|
||||
|
||||
#define A(expect, expr) \
|
||||
Assert (expect == __builtin_has_attribute (expr, aligned)) \
|
||||
|
||||
enum { PA = __alignof__ (void*) };
|
||||
|
||||
/* Define pointer to pointer types, with different alignments
|
||||
at each level of indirection. */
|
||||
typedef struct S8 { char a[8]; } S8;
|
||||
typedef ALIGN (8) S8 I8;
|
||||
typedef ALIGN (16) I8 *P16_I8;
|
||||
typedef P16_I8 *P_P16_I8;
|
||||
typedef ALIGN (32) P_P16_I8 *P32_P_P16_I8;
|
||||
typedef P32_P_P16_I8 *P_P32_P_P16_I8;
|
||||
typedef ALIGN (64) P_P32_P_P16_I8 *P64_P_P32_P_P16_I8;
|
||||
|
||||
Assert ( 8 == __alignof__ (I8));
|
||||
Assert (16 == __alignof__ (P16_I8));
|
||||
Assert (PA == __alignof__ (P_P16_I8));
|
||||
Assert (32 == __alignof__ (P32_P_P16_I8));
|
||||
Assert (PA == __alignof__ (P_P32_P_P16_I8));
|
||||
Assert (64 == __alignof__ (P64_P_P32_P_P16_I8));
|
||||
|
||||
|
||||
/* Similar to the pointer of pointers above, define array of array
|
||||
types, with different alignments at each level of indirection. */
|
||||
typedef struct S64 { char a[64]; } S64;
|
||||
typedef ALIGN (64) S64 I64;
|
||||
typedef ALIGN (32) I64 A32_I64[3];
|
||||
typedef A32_I64 A_A32_I64[5];
|
||||
typedef ALIGN (16) A_A32_I64 A16_A_A32_I64[7];
|
||||
typedef A16_A_A32_I64 A_A16_A_A32_I64[11];
|
||||
typedef ALIGN (8) A_A16_A_A32_I64 A8_A_A16_A_A32_I64[13];
|
||||
|
||||
Assert (64 == __alignof__ (I64));
|
||||
Assert (32 == __alignof__ (A32_I64));
|
||||
/* With no explicit alignment, an array of overaligned elements
|
||||
is considered to have the alignment of its elements. */
|
||||
Assert (32 == __alignof__ (A_A32_I64));
|
||||
Assert (16 == __alignof__ (A16_A_A32_I64));
|
||||
Assert (16 == __alignof__ (A_A16_A_A32_I64));
|
||||
Assert ( 8 == __alignof__ (A8_A_A16_A_A32_I64));
|
||||
|
||||
|
||||
void test_arrays (void)
|
||||
{
|
||||
/* Verify that the aligned attribute on each of the composite types
|
||||
is detected corresponding to the result of __alignof__. */
|
||||
A (1, (*(A8_A_A16_A_A32_I64*)0));
|
||||
A3 (1, (*(A8_A_A16_A_A32_I64*)0), 8);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 8);
|
||||
/* GCC propagates the user-align bit from element types to their
|
||||
arrays but it doesn't propagate the attribute itself. The built-in
|
||||
considers both the bit and the attribute so it succeeds below even
|
||||
though the referenced type isn't declared with the attribute. */
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 8);
|
||||
A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0], 16);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 32);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1], 8);
|
||||
A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1], 16);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1], 32);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 16);
|
||||
A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 32);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 64);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 16);
|
||||
A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 32);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 64);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 32);
|
||||
A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 64);
|
||||
A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 128);
|
||||
|
||||
A8_A_A16_A_A32_I64 a;
|
||||
A3 (0, a[0], 8);
|
||||
A3 (1, a[0], 16);
|
||||
A3 (0, a[0], 32);
|
||||
A3 (0, a[0][1], 8);
|
||||
A3 (1, a[0][1], 16);
|
||||
A3 (0, a[0][1], 32);
|
||||
A3 (0, a[0][1][2], 16);
|
||||
A3 (1, a[0][1][2], 32);
|
||||
A3 (0, a[0][1][2], 64);
|
||||
A3 (0, a[0][1][2][3], 16);
|
||||
A3 (1, a[0][1][2][3], 32);
|
||||
A3 (0, a[0][1][2][3], 64);
|
||||
A3 (0, a[0][1][2][3][4], 32);
|
||||
A3 (1, a[0][1][2][3][4], 64);
|
||||
A3 (0, a[0][1][2][3][4], 128);
|
||||
}
|
||||
|
||||
void test_pointers (void)
|
||||
{
|
||||
/* Verify that the aligned attribute on each of the composite pointer
|
||||
types is detected corresponding to the result of __alignof__. */
|
||||
A (1, I8);
|
||||
A3 (0, I8, 4);
|
||||
A3 (1, I8, 8);
|
||||
|
||||
A (1, P16_I8);
|
||||
A3 (0, P16_I8, 8);
|
||||
A3 (1, P16_I8, 16);
|
||||
|
||||
A (0, P_P16_I8);
|
||||
A3 (0, P_P16_I8, 8);
|
||||
A3 (0, P_P16_I8, 16);
|
||||
|
||||
A (1, P32_P_P16_I8);
|
||||
A3 (0, P32_P_P16_I8, 8);
|
||||
A3 (0, P32_P_P16_I8, 16);
|
||||
A3 (1, P32_P_P16_I8, 32);
|
||||
|
||||
A (0, P_P32_P_P16_I8);
|
||||
|
||||
A (1, P64_P_P32_P_P16_I8);
|
||||
A3 (0, P64_P_P32_P_P16_I8, 8);
|
||||
A3 (0, P64_P_P32_P_P16_I8, 16);
|
||||
A3 (0, P64_P_P32_P_P16_I8, 32);
|
||||
A3 (1, P64_P_P32_P_P16_I8, 64);
|
||||
|
||||
|
||||
/* Verify that the attribute on each of the composite types is detected
|
||||
in the type of each of the indirection expressions. */
|
||||
A (1, *(P16_I8)0);
|
||||
A3 (1, *(P16_I8)0, 8);
|
||||
A3 (0, *(P16_I8)0, 16);
|
||||
|
||||
A (1, *(P_P16_I8)0);
|
||||
A3 (0, *(P_P16_I8)0, 8);
|
||||
A3 (1, *(P_P16_I8)0, 16);
|
||||
|
||||
A (0, *(P32_P_P16_I8)0);
|
||||
A3 (0, *(P32_P_P16_I8)0, 8);
|
||||
A3 (0, *(P32_P_P16_I8)0, 16);
|
||||
A3 (0, *(P32_P_P16_I8)0, 32);
|
||||
|
||||
A (1, *(P_P32_P_P16_I8)0);
|
||||
A3 (1, *(P_P32_P_P16_I8)0, 32);
|
||||
|
||||
A (0, *(P64_P_P32_P_P16_I8)0);
|
||||
|
||||
/* Verify that the attribute on each of the composite types is detected
|
||||
in the type of each of the subscipting expressions. */
|
||||
A (1, ((P16_I8)0)[0]);
|
||||
A3 (1, ((P16_I8)0)[1], 8);
|
||||
A3 (0, ((P16_I8)0)[2], 16);
|
||||
|
||||
A (1, ((P_P16_I8)0)[3]);
|
||||
A3 (0, ((P_P16_I8)0)[4], 8);
|
||||
A3 (1, ((P_P16_I8)0)[5], 16);
|
||||
|
||||
A (0, ((P32_P_P16_I8)0)[6]);
|
||||
A3 (0, ((P32_P_P16_I8)0)[7], 8);
|
||||
A3 (0, ((P32_P_P16_I8)0)[8], 16);
|
||||
A3 (0, ((P32_P_P16_I8)0)[9], 32);
|
||||
|
||||
A (1, ((P_P32_P_P16_I8)0)[10]);
|
||||
A3 (1, ((P_P32_P_P16_I8)0)[11], 32);
|
||||
|
||||
A (0, ((P64_P_P32_P_P16_I8)0)[12]);
|
||||
|
||||
|
||||
/* Verify that the attribute on each of the composite types is detected
|
||||
in the type of each of the subscipting expression involving variables. */
|
||||
|
||||
I8 i8;
|
||||
P16_I8 p16_i8 = &i8;
|
||||
P_P16_I8 p_p16_i8 = &p16_i8;
|
||||
P32_P_P16_I8 p32_p_p16_i8 = &p_p16_i8;
|
||||
P_P32_P_P16_I8 p_p32_p_p16_i8 = &p32_p_p16_i8;
|
||||
P64_P_P32_P_P16_I8 p64_p_p32_p_p16_i8 = &p_p32_p_p16_i8;
|
||||
|
||||
A (1, p16_i8[0]);
|
||||
A3 (1, p16_i8[1], 8);
|
||||
A3 (0, p16_i8[2], 16);
|
||||
|
||||
A (1, p_p16_i8[3]);
|
||||
A3 (0, p_p16_i8[4], 8);
|
||||
A3 (1, p_p16_i8[5], 16);
|
||||
|
||||
A (0, p32_p_p16_i8[6]);
|
||||
A3 (0, p32_p_p16_i8[7], 8);
|
||||
A3 (0, p32_p_p16_i8[8], 16);
|
||||
A3 (0, p32_p_p16_i8[9], 32);
|
||||
|
||||
A (1, p_p32_p_p16_i8[10]);
|
||||
A3 (1, p_p32_p_p16_i8[11], 32);
|
||||
|
||||
|
||||
A (1, p_p16_i8[0][1]);
|
||||
A3 (1, p_p16_i8[1][2], 8);
|
||||
A3 (0, p_p16_i8[2][3], 16);
|
||||
|
||||
|
||||
A (0, p64_p_p32_p_p16_i8[0]);
|
||||
|
||||
A (1, p64_p_p32_p_p16_i8[0][1]);
|
||||
A3 (0, p64_p_p32_p_p16_i8[0][2], 16);
|
||||
A3 (1, p64_p_p32_p_p16_i8[0][3], 32);
|
||||
A3 (0, p64_p_p32_p_p16_i8[0][4], 64);
|
||||
|
||||
A (0, p64_p_p32_p_p16_i8[0][1][2]);
|
||||
|
||||
A (1, p64_p_p32_p_p16_i8[0][1][2][3]);
|
||||
A3 (0, p64_p_p32_p_p16_i8[0][1][2][4], 8);
|
||||
A3 (1, p64_p_p32_p_p16_i8[0][1][2][4], 16);
|
||||
A3 (0, p64_p_p32_p_p16_i8[0][1][2][4], 32);
|
||||
|
||||
A (1, p64_p_p32_p_p16_i8[0][1][2][3][4]);
|
||||
A3 (1, p64_p_p32_p_p16_i8[0][1][2][3][5], 8);
|
||||
A3 (0, p64_p_p32_p_p16_i8[0][1][2][4][6], 16);
|
||||
|
||||
|
||||
/* Same as above but using the indirection expression. */
|
||||
A (0, *p64_p_p32_p_p16_i8);
|
||||
|
||||
A (1, **p64_p_p32_p_p16_i8);
|
||||
A3 (0, **p64_p_p32_p_p16_i8, 16);
|
||||
A3 (1, **p64_p_p32_p_p16_i8, 32);
|
||||
A3 (0, **p64_p_p32_p_p16_i8, 64);
|
||||
|
||||
A (0, ***p64_p_p32_p_p16_i8);
|
||||
|
||||
A (1, ****p64_p_p32_p_p16_i8);
|
||||
A3 (0, ****p64_p_p32_p_p16_i8, 8);
|
||||
A3 (1, ****p64_p_p32_p_p16_i8, 16);
|
||||
A3 (0, ****p64_p_p32_p_p16_i8, 32);
|
||||
|
||||
A (1, *****p64_p_p32_p_p16_i8);
|
||||
A3 (1, *****p64_p_p32_p_p16_i8, 8);
|
||||
A3 (0, *****p64_p_p32_p_p16_i8, 16);
|
||||
}
|
||||
|
||||
|
||||
S8 f_S8 (void);
|
||||
I8 f_I8 (void);
|
||||
P16_I8 f_P16_I8 (void);
|
||||
P_P16_I8 f_P_P16_I8 (void);
|
||||
P32_P_P16_I8 f_P32_P_P16_I8 (void);
|
||||
P_P32_P_P16_I8 f_P_P32_P_P16_I8 (void);
|
||||
P64_P_P32_P_P16_I8 f_P64_P_P32_P_P16_I8 (void);
|
||||
|
||||
void test_function_call (void)
|
||||
{
|
||||
/* Verify that the aligned attribute on each of the composite pointer
|
||||
types returned by the functions is detected corresponding to
|
||||
the result of __alignof__. */
|
||||
|
||||
A (0, f_S8 ());
|
||||
|
||||
A (1, f_I8 ());
|
||||
A3 (1, f_I8 (), 8);
|
||||
A3 (0, f_I8 (), 16);
|
||||
|
||||
A (1, f_P16_I8 ());
|
||||
A3 (0, f_P16_I8 (), 8);
|
||||
A3 (1, f_P16_I8 (), 16);
|
||||
A3 (0, f_P16_I8 (), 32);
|
||||
|
||||
A (1, *f_P16_I8 ());
|
||||
A3 (1, *f_P16_I8 (), 8);
|
||||
A3 (0, *f_P16_I8 (), 16);
|
||||
|
||||
A (0, f_P_P16_I8 ());
|
||||
|
||||
A (1, *f_P_P16_I8 ());
|
||||
A3 (0, *f_P_P16_I8 (), 8);
|
||||
A3 (1, *f_P_P16_I8 (), 16);
|
||||
A3 (0, *f_P_P16_I8 (), 32);
|
||||
|
||||
A (1, **f_P_P16_I8 ());
|
||||
A3 (1, **f_P_P16_I8 (), 8);
|
||||
A3 (0, **f_P_P16_I8 (), 16);
|
||||
A3 (0, **f_P_P16_I8 (), 32);
|
||||
}
|
||||
|
||||
|
||||
void test_compound_literal (void)
|
||||
{
|
||||
A (0, (S8){ });
|
||||
|
||||
A (1, (I8){ });
|
||||
A3 (1, (I8){ }, 8);
|
||||
A3 (0, (I8){ }, 16);
|
||||
|
||||
A (1, (I64){ });
|
||||
A3 (0, (I64){ }, 8);
|
||||
A3 (0, (I64){ }, 16);
|
||||
A3 (0, (I64){ }, 32);
|
||||
A3 (1, (I64){ }, 64);
|
||||
|
||||
A (1, (A32_I64){ 0 });
|
||||
A3 (0, (A32_I64){ 0 }, 8);
|
||||
A3 (0, (A32_I64){ 0 }, 16);
|
||||
A3 (1, (A32_I64){ 0 }, 32);
|
||||
A3 (0, (A32_I64){ 0 }, 64);
|
||||
|
||||
A (1, ((A32_I64){ 0 })[0]);
|
||||
A3 (0, ((A32_I64){ 0 })[0], 8);
|
||||
A3 (0, ((A32_I64){ 0 })[0], 16);
|
||||
A3 (0, ((A32_I64){ 0 })[0], 32);
|
||||
A3 (1, ((A32_I64){ 0 })[0], 64);
|
||||
}
|
||||
|
||||
|
||||
void test_ternary_expression (int i)
|
||||
{
|
||||
A (0, (0 ? (S8){ } : (S8){ }));
|
||||
|
||||
A (1, (1 ? (I8){ } : (I8){ }));
|
||||
A3 (1, (2 ? (I8){ } : (I8){ }), 8);
|
||||
A3 (0, (3 ? (I8){ } : (I8){ }), 16);
|
||||
|
||||
A (1, (4 ? (I64){ } : (I64){ }));
|
||||
A3 (0, (5 ? (I64){ } : (I64){ }), 8);
|
||||
A3 (0, (6 ? (I64){ } : (I64){ }), 16);
|
||||
A3 (0, (7 ? (I64){ } : (I64){ }), 32);
|
||||
A3 (1, (8 ? (I64){ } : (I64){ }), 64);
|
||||
|
||||
#if !__cplusplus
|
||||
/* Suppress -Wc++-compat warning: converting an array compound literal
|
||||
to a pointer is ill-formed in C++ */
|
||||
# pragma GCC diagnostic ignored "-Wc++-compat"
|
||||
|
||||
A (0, (9 ? (A32_I64){ } : (A32_I64){ }));
|
||||
A3 (0, (i ? (A32_I64){ } : (A32_I64){ }), 8);
|
||||
A3 (0, (i++ ? (A32_I64){ } : (A32_I64){ }), 16);
|
||||
A3 (0, (++i ? (A32_I64){ } : (A32_I64){ }), 32);
|
||||
A3 (0, (!i ? (A32_I64){ } : (A32_I64){ }), 64);
|
||||
|
||||
A (1, (0 ? (A32_I64){ } : (A32_I64){ })[0]);
|
||||
A3 (0, (1 ? (A32_I64){ } : (A32_I64){ })[1], 8);
|
||||
A3 (0, (2 ? (A32_I64){ } : (A32_I64){ })[2], 16);
|
||||
A3 (0, (3 ? (A32_I64){ } : (A32_I64){ })[3], 32);
|
||||
A3 (1, (3 ? (A32_I64){ } : (A32_I64){ })[i], 64);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void test_comma_expression (int i)
|
||||
{
|
||||
#if __cplusplus
|
||||
/* In C++, the type of the comma expressions whose operand is an array
|
||||
is the array itself with any attributes it was defined with. */
|
||||
# define R 1
|
||||
#else
|
||||
/* In C, the type of the comma expressions whose operand is an array
|
||||
is a pointer type that does not include any attributes the array
|
||||
was defined with. */
|
||||
# define R 0
|
||||
/* Suppress -Wc++-compat warning: converting an array compound literal
|
||||
to a pointer is ill-formed in C++
|
||||
G++ accepts the conversion in unevaluated contexts without a warning. */
|
||||
# pragma GCC diagnostic ignored "-Wc++-compat"
|
||||
#endif
|
||||
|
||||
A (0, (0, (S8){ }));
|
||||
|
||||
A (1, (0, (I8){ }));
|
||||
A3 (1, (1, (I8){ }), 8);
|
||||
A3 (0, (2, (I8){ }), 16);
|
||||
|
||||
A (1, (3, (I64){ }));
|
||||
A3 (0, (4, (I64){ }), 8);
|
||||
A3 (0, (5, (I64){ }), 16);
|
||||
A3 (0, (6, (I64){ }), 32);
|
||||
A3 (1, (7, (I64){ }), 64);
|
||||
|
||||
A (R, (8, (A32_I64){ }));
|
||||
A3 (0, (9, (A32_I64){ }), 8);
|
||||
A3 (0, ((void)0, (A32_I64){ }), 16);
|
||||
A3 (R, ((I64){ },(A32_I64){ }), 32);
|
||||
A3 (0, (0, (A32_I64){ }), 64);
|
||||
|
||||
A (1, (1, ((A32_I64){ })[0]));
|
||||
A3 (0, (2, ((A32_I64){ })[0]), 8);
|
||||
A3 (0, (i++, ((A32_I64){ })[0]), 16);
|
||||
A3 (0, (++i, ((A32_I64){ })[0]), 32);
|
||||
A3 (1, (i = 0, ((A32_I64){ })[0]), 64);
|
||||
}
|
|
@ -11,5 +11,5 @@ int fn6 (const char *, ...) __attribute__ ((sentinel (fn1))); /* { dg-warning "n
|
|||
void* fn7 (void) __attribute__ ((alloc_align (fn1))); /* { dg-warning ".alloc_align. attribute argument has type .int\\\(int\\\)." } */
|
||||
void* fn8 (void) __attribute__ ((assume_aligned (fn1))); /* { dg-warning "not an integer constant" } */
|
||||
|
||||
typedef int __attribute__((vector_size (fn1))) v4si; /* { dg-warning "attribute ignored" } */
|
||||
typedef int __attribute__((vector_size (fn1))) v4si; /* { dg-error "'vector_size' attribute argument value 'fn1' is not an integer constant" } */
|
||||
typedef int T __attribute__((aligned (fn1))); /* { dg-error "requested alignment is not" } */
|
||||
|
|
69
gcc/testsuite/gcc.dg/attr-vector_size.c
Normal file
69
gcc/testsuite/gcc.dg/attr-vector_size.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* PR middle-end/89797 - ICE on a vector_size (1LU << 33) int variable
|
||||
PR c/89798 - excessive vector_size silently accepted and truncated
|
||||
{ dg-do compile { target int32plus } }
|
||||
{ dg-options "-Wall -Wno-unused" } */
|
||||
|
||||
#define ASSERT(e) _Static_assert (e, #e)
|
||||
#define VEC(N) __attribute__ ((vector_size (N)))
|
||||
#define POW2(N) (1LLU << N)
|
||||
#define CAT(a, b) a ## b
|
||||
#define CONCAT(a, b) CAT (a, b)
|
||||
|
||||
#define DEFVEC(storage, N) \
|
||||
typedef VEC (POW2 (N)) char CONCAT (Vec, N); \
|
||||
storage CONCAT (Vec, N) CONCAT (v, N); \
|
||||
ASSERT (sizeof (CONCAT (Vec, N)) == POW2 (N)); \
|
||||
ASSERT (sizeof (CONCAT (v, N)) == POW2 (N))
|
||||
|
||||
DEFVEC (extern, 27);
|
||||
DEFVEC (extern, 28);
|
||||
DEFVEC (extern, 29);
|
||||
DEFVEC (extern, 30);
|
||||
|
||||
#if __SIZEOF_SIZE_T__ > 4
|
||||
|
||||
DEFVEC (extern, 31);
|
||||
DEFVEC (extern, 32);
|
||||
DEFVEC (extern, 33);
|
||||
DEFVEC (extern, 34);
|
||||
DEFVEC (extern, 60);
|
||||
DEFVEC (extern, 61);
|
||||
DEFVEC (extern, 62);
|
||||
|
||||
VEC (POW2 (63)) char v63; /* { dg-error "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */
|
||||
|
||||
#else
|
||||
|
||||
VEC (POW2 (31)) char v31; /* { dg-error "'vector_size' attribute argument value '2147483648' exceeds 2147483647" "ILP32" { target ilp32 } } */
|
||||
|
||||
VEC (POW2 (32)) char v32; /* { dg-error "'vector_size' attribute argument value '4294967296' exceeds 2147483647" "ILP32" { target ilp32 } } */
|
||||
|
||||
#endif
|
||||
|
||||
void test_local_scope (void)
|
||||
{
|
||||
DEFVEC (auto, 27);
|
||||
DEFVEC (auto, 28);
|
||||
DEFVEC (auto, 29);
|
||||
DEFVEC (auto, 30);
|
||||
|
||||
#if __SIZEOF_SIZE_T__ > 4
|
||||
|
||||
DEFVEC (auto, 31);
|
||||
DEFVEC (auto, 32);
|
||||
DEFVEC (auto, 33);
|
||||
DEFVEC (auto, 34);
|
||||
DEFVEC (auto, 60);
|
||||
DEFVEC (auto, 61);
|
||||
DEFVEC (auto, 62);
|
||||
|
||||
VEC (POW2 (63)) char v63; /* { dg-error "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */
|
||||
|
||||
#else
|
||||
|
||||
VEC (POW2 (31)) char v31; /* { dg-error "'vector_size' attribute argument value '2147483648' exceeds 2147483647" "ILP32" { target ilp32 } } */
|
||||
|
||||
VEC (POW2 (32)) char v32; /* { dg-error "'vector_size' attribute argument value '4294967296' exceeds 2147483647" "ILP32" { target ilp32 } } */
|
||||
|
||||
#endif
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
#define vs(n) __attribute__((vector_size (n)))
|
||||
int vs (-1) a; /* { dg-warning "attribute ignored" } */
|
||||
int vs (-1) a; /* { dg-error ".vector_size. attribute argument value '-1' is negative" } */
|
||||
int vs (0) b; /* { dg-error "zero vector size" } */
|
||||
int vs (1) c; /* { dg-error "multiple of component size" } */
|
||||
int vs (sizeof (int) / 2) d; /* { dg-error "multiple of component size" } */
|
||||
|
|
|
@ -3741,7 +3741,7 @@ TYPE_VECTOR_SUBPARTS (const_tree node)
|
|||
return res;
|
||||
}
|
||||
else
|
||||
return 1 << precision;
|
||||
return (unsigned HOST_WIDE_INT)1 << precision;
|
||||
}
|
||||
|
||||
/* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must
|
||||
|
|
Loading…
Add table
Reference in a new issue