Commit 3fb82380 by Martin Sebor Committed by Martin Sebor

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
parent 3d8695f5
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> 2019-04-12 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/89965 PR rtl-optimization/89965
* dce.c: Include rtl-iter.h. * dce.c: Include rtl-iter.h.
(struct check_argument_load_data): New type. (struct check_argument_load_data): New type.
......
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> 2019-04-12 Jason Merrill <jason@redhat.com>
* call.c (null_member_pointer_value_p): Handle an empty CONSTRUCTOR * call.c (null_member_pointer_value_p): Handle an empty CONSTRUCTOR
......
...@@ -8555,9 +8555,9 @@ cp_parser_has_attribute_expression (cp_parser *parser) ...@@ -8555,9 +8555,9 @@ cp_parser_has_attribute_expression (cp_parser *parser)
cp_parser_parse_definitely (parser); cp_parser_parse_definitely (parser);
/* If the type-id production did not work out, then we must be /* 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) if (!oper || oper == error_mark_node)
oper = cp_parser_unary_expression (parser); oper = cp_parser_assignment_expression (parser);
STRIP_ANY_LOCATION_WRAPPER (oper); STRIP_ANY_LOCATION_WRAPPER (oper);
...@@ -1247,14 +1247,18 @@ constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align) ...@@ -1247,14 +1247,18 @@ constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align)
return 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 HOST_WIDE_INT
default_vector_alignment (const_tree type) default_vector_alignment (const_tree type)
{ {
HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type)); unsigned HOST_WIDE_INT align = MAX_OFILE_ALIGNMENT;
if (align > MAX_OFILE_ALIGNMENT) tree size = TYPE_SIZE (type);
align = MAX_OFILE_ALIGNMENT; if (tree_fits_uhwi_p (size))
return align; align = tree_to_uhwi (size);
return align < MAX_OFILE_ALIGNMENT ? align : MAX_OFILE_ALIGNMENT;
} }
/* The default implementation of /* The default implementation of
......
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> 2019-04-12 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/89965 PR rtl-optimization/89965
* gcc.target/i386/pr89965.c: New test. * gcc.target/i386/pr89965.c: New test.
......
...@@ -4,7 +4,7 @@ ...@@ -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_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" } */ 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" } */ void f1(char*) __attribute__((nonnull(bar))); /* { dg-warning ".nonnull. attribute argument is invalid" } */
...@@ -14,7 +14,7 @@ void foo(int); ...@@ -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_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\\\)" } */ 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 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\\\)." } */ void f2(char*) __attribute__((nonnull(1,foo))); /* { dg-warning ".nonnull. attribute argument 2 has type .void ?\\\(int\\\)." } */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
{ dg-skip-if "No section attribute" { { hppa*-*-hpux* } && { ! lp64 } } } { dg-skip-if "No section attribute" { { hppa*-*-hpux* } && { ! lp64 } } }
{ dg-options "-Wall -ftrack-macro-expansion=0" } { dg-options "-Wall -ftrack-macro-expansion=0" }
{ dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } } { 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__)) #define ATTR(...) __attribute__ ((__VA_ARGS__))
...@@ -155,7 +155,8 @@ void test_packed (struct PackedMember *p) ...@@ -155,7 +155,8 @@ void test_packed (struct PackedMember *p)
A (0, gpak[0].c, packed); A (0, gpak[0].c, packed);
A (0, gpak[1].s, packed); A (0, gpak[1].s, packed);
A (1, gpak->a, 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 /* The following fails because in C it's represented as
INDIRECT_REF (POINTER_PLUS (NOP_EXPR (ADDR_EXPR (gpak)), ...)) INDIRECT_REF (POINTER_PLUS (NOP_EXPR (ADDR_EXPR (gpak)), ...))
...@@ -165,7 +166,8 @@ void test_packed (struct PackedMember *p) ...@@ -165,7 +166,8 @@ void test_packed (struct PackedMember *p)
A (0, p->c, packed); A (0, p->c, packed);
A (0, p->s, packed); A (0, p->s, packed);
A (1, p->a, 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. /* Similar to the comment above.
A (1, *p->a, packed); */ A (1, *p->a, packed); */
} }
...@@ -218,13 +220,68 @@ void test_vector_size (void) ...@@ -218,13 +220,68 @@ void test_vector_size (void)
A (1, iv16, vector_size (16)); A (1, iv16, vector_size (16));
A (0, iv16, vector_size (32)); 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]; 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 (1));
A (0, afv8, vector_size (2)); A (0, afv8, vector_size (2));
A (0, afv8, vector_size (4)); 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 (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));
} }
......
/* 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));
}
...@@ -11,5 +11,5 @@ int fn6 (const char *, ...) __attribute__ ((sentinel (fn1))); /* { dg-warning "n ...@@ -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* 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" } */ 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" } */ typedef int T __attribute__((aligned (fn1))); /* { dg-error "requested alignment is not" } */
/* 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 @@ ...@@ -2,7 +2,7 @@
/* { dg-do compile } */ /* { dg-do compile } */
#define vs(n) __attribute__((vector_size (n))) #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 (0) b; /* { dg-error "zero vector size" } */
int vs (1) c; /* { dg-error "multiple of component size" } */ int vs (1) c; /* { dg-error "multiple of component size" } */
int vs (sizeof (int) / 2) d; /* { 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) ...@@ -3741,7 +3741,7 @@ TYPE_VECTOR_SUBPARTS (const_tree node)
return res; return res;
} }
else else
return 1 << precision; return (unsigned HOST_WIDE_INT)1 << precision;
} }
/* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must /* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment