Commit 4569f8b3 by Sandra Loosemore Committed by Sandra Loosemore

Fix bugs relating to flexibly-sized objects in nios2 backend.

2019-12-01  Sandra Loosemore  <sandra@codesourcery.com>

	Fix bugs relating to flexibly-sized objects in nios2 backend.

	PR target/92499

	gcc/c/
	* c-decl.c (flexible_array_type_p): Move to common code.

	gcc/
	* config/nios2/nios2.c (nios2_in_small_data_p): Do not consider
	objects of flexible types to be small if they have internal linkage
	or are declared extern.
	* config/nios2/nios2.h (ASM_OUTPUT_ALIGNED_LOCAL): Replace with...
	(ASM_OUTPUT_ALIGNED_DECL_LOCAL): ...this.  Use targetm.in_small_data_p
	instead of the size of the object initializer.
	* tree.c (flexible_array_type_p): Move from C front end, and
	generalize to handle fields in non-C structures.
	* tree.h (flexible_array_type_p): Declare.

	gcc/testsuite/
	* gcc.target/nios2/pr92499-1.c: New.
	* gcc.target/nios2/pr92499-2.c: New.
	* gcc.target/nios2/pr92499-3.c: New.

From-SVN: r278891
parent e549dd44
2019-12-01 Sandra Loosemore <sandra@codesourcery.com>
PR target/92499
* config/nios2/nios2.c (nios2_in_small_data_p): Do not consider
objects of flexible types to be small if they have internal linkage
or are declared extern.
* config/nios2/nios2.h (ASM_OUTPUT_ALIGNED_LOCAL): Replace with...
(ASM_OUTPUT_ALIGNED_DECL_LOCAL): ...this. Use targetm.in_small_data_p
instead of the size of the object initializer.
* tree.c (flexible_array_type_p): Move from C front end, and
generalize to handle fields in non-C structures.
* tree.h (flexible_array_type_p): Declare.
2019-11-30 Jan Hubicka <hubicka@ucw.cz>
* profile-count.h (profile_count::operator<): Use IPA value for
2019-12-01 Sandra Loosemore <sandra@codesourcery.com>
PR target/92499
* c-decl.c (flexible_array_type_p): Move to common code.
2019-11-30 Richard Sandiford <richard.sandiford@arm.com>
* c-decl.c (start_decl): Allow initialization of variables whose
......
......@@ -5709,39 +5709,6 @@ check_compound_literal_type (location_t loc, struct c_type_name *type_name)
"defining a type in a compound literal is invalid in C++");
}
/* Determine whether TYPE is a structure with a flexible array member,
or a union containing such a structure (possibly recursively). */
static bool
flexible_array_type_p (tree type)
{
tree x;
switch (TREE_CODE (type))
{
case RECORD_TYPE:
x = TYPE_FIELDS (type);
if (x == NULL_TREE)
return false;
while (DECL_CHAIN (x) != NULL_TREE)
x = DECL_CHAIN (x);
if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
&& TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
&& TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
&& TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
return true;
return false;
case UNION_TYPE:
for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
{
if (flexible_array_type_p (TREE_TYPE (x)))
return true;
}
return false;
default:
return false;
}
}
/* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME,
replacing with appropriate values if they are invalid. */
......
......@@ -2373,6 +2373,22 @@ nios2_in_small_data_p (const_tree exp)
if (nios2_small_section_name_p (section))
return true;
}
else if (flexible_array_type_p (TREE_TYPE (exp))
&& (!TREE_PUBLIC (exp) || DECL_EXTERNAL (exp)))
{
/* We really should not consider any objects of any flexibly-sized
type to be small data, but pre-GCC 10 did not test
for this and just fell through to the next case. Thus older
code compiled with -mgpopt=global could contain GP-relative
accesses to objects defined in this compilation unit with
external linkage. We retain the possible small-data treatment
of such definitions for backward ABI compatibility, but
no longer generate GP-relative accesses for external
references (so that the ABI could be changed in the future
with less potential impact), or objects with internal
linkage. */
return false;
}
else
{
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
......
......@@ -467,10 +467,10 @@ while (0)
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
if ((SIZE) <= nios2_section_threshold) \
if (targetm.in_small_data_p (DECL)) \
switch_to_section (sbss_section); \
else \
switch_to_section (bss_section); \
......
2019-12-01 Sandra Loosemore <sandra@codesourcery.com>
PR target/92499
* gcc.target/nios2/pr92499-1.c: New.
* gcc.target/nios2/pr92499-2.c: New.
* gcc.target/nios2/pr92499-3.c: New.
2019-12-02 Luo Xiong Hu <luoxhu@linux.ibm.com>
testsuite/pr92398
......
/* PR target/92499 */
/* { dg-do compile } */
/* { dg-options "-O2 -mgpopt=global -G8" } */
/* Check placement and addressing of flexibly-sized objects with internal
linkage. */
enum { size = 100 };
struct flexible
{
int length;
int data[];
};
static struct flexible local_flexible =
{
.data = { [size - 1] = 0, }
};
static struct flexible local_flexible_nonzero =
{
.length = size,
.data = { [size - 1] = 0, }
};
struct flexible *
get_local_flexible (void)
{
return &local_flexible;
}
struct flexible *
get_local_flexible_nonzero (void)
{
return &local_flexible_nonzero;
}
/* We should not place the flexibly-sized objects in small data
sections, or generate gp-relative addresses for them. */
/* { dg-final { scan-assembler-not "\\.sdata" } } */
/* { dg-final { scan-assembler-not "\\.sbss" } } */
/* { dg-final { scan-assembler-not "%gprel\(.*flexible.*\)" } } */
/* PR target/92499 */
/* { dg-do compile } */
/* { dg-options "-O2 -mgpopt=global -G8" } */
/* Check placement and addressing of flexibly-sized objects with external
linkage. */
enum { size = 100 };
struct flexible
{
int length;
int data[];
};
extern struct flexible global_flexible;
struct flexible global_flexible =
{
.data = { [size - 1] = 0, }
};
extern struct flexible global_flexible_nonzero;
struct flexible global_flexible_nonzero =
{
.length = size,
.data = { [size - 1] = 0, }
};
struct flexible *
get_global_flexible (void)
{
return &global_flexible;
}
struct flexible *
get_global_flexible_nonzero (void)
{
return &global_flexible_nonzero;
}
/* To preserve ABI compatibility we place the flexibly-sized objects in
small data sections. */
/* { dg-final { scan-assembler-times "\\.sdata" 1 } } */
/* { dg-final { scan-assembler-times "\\.sbss" 1 } } */
/* PR target/92499 */
/* { dg-do compile } */
/* { dg-options "-O2 -mgpopt=global -G8" } */
/* Check addressing of extern flexibly-sized objects. */
struct flexible
{
int length;
int data[];
};
extern struct flexible extern_flexible;
struct flexible *
get_extern_flexible (void)
{
return &extern_flexible;
}
/* We should not generate GP-relative addresses for external objects of
unknown size. */
/* { dg-final { scan-assembler-not "%gprel\(.*flexible.*\)" } } */
......@@ -15003,6 +15003,41 @@ default_is_empty_record (const_tree type)
return default_is_empty_type (TYPE_MAIN_VARIANT (type));
}
/* Determine whether TYPE is a structure with a flexible array member,
or a union containing such a structure (possibly recursively). */
bool
flexible_array_type_p (const_tree type)
{
tree x, last;
switch (TREE_CODE (type))
{
case RECORD_TYPE:
last = NULL_TREE;
for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
if (TREE_CODE (x) == FIELD_DECL)
last = x;
if (last == NULL_TREE)
return false;
if (TREE_CODE (TREE_TYPE (last)) == ARRAY_TYPE
&& TYPE_SIZE (TREE_TYPE (last)) == NULL_TREE
&& TYPE_DOMAIN (TREE_TYPE (last)) != NULL_TREE
&& TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (last))) == NULL_TREE)
return true;
return false;
case UNION_TYPE:
for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
{
if (TREE_CODE (x) == FIELD_DECL
&& flexible_array_type_p (TREE_TYPE (x)))
return true;
}
return false;
default:
return false;
}
}
/* Like int_size_in_bytes, but handle empty records specially. */
HOST_WIDE_INT
......
......@@ -6138,6 +6138,7 @@ extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
extern bool nonnull_arg_p (const_tree);
extern bool default_is_empty_record (const_tree);
extern bool flexible_array_type_p (const_tree);
extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree);
extern tree arg_size_in_bytes (const_tree);
extern bool expr_type_first_operand_type_p (tree_code);
......
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