From: Eric Botcazou Date: Fri, 7 Mar 2008 17:45:09 +0000 (+0000) Subject: decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously large alignments specifi... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fd5c81e9083eb241aa14a4ff428042fe98c15c88;p=gcc.git decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously large alignments specified for types. * decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously large alignments specified for types. (validate_alignment): Minor cleanup. From-SVN: r133012 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 44879fd8c7b..9d92d7b732f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2008-03-07 Eric Botcazou + + * decl.c (gnat_to_gnu_entity): Issue a warning on suspiciously + large alignments specified for types. + (validate_alignment): Minor cleanup. + 2008-03-07 Eric Botcazou * decl.c (MAX_FIXED_MODE_SIZE): Define if not already defined. diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index 7c75666f5d4..48279391b30 100644 --- a/gcc/ada/decl.c +++ b/gcc/ada/decl.c @@ -4086,8 +4086,38 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if (align != 0 || TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE) ; else if (Known_Alignment (gnat_entity)) - align = validate_alignment (Alignment (gnat_entity), gnat_entity, - TYPE_ALIGN (gnu_type)); + { + align = validate_alignment (Alignment (gnat_entity), gnat_entity, + TYPE_ALIGN (gnu_type)); + + /* Warn on suspiciously large alignments. This should catch + errors about the (alignment,byte)/(size,bit) discrepancy. */ + if (align > BIGGEST_ALIGNMENT && Has_Alignment_Clause (gnat_entity)) + { + tree size; + + /* If a size was specified, take it into account. Otherwise + use the RM size for records as the type size has already + been adjusted to the alignment. */ + if (gnu_size) + size = gnu_size; + else if ((TREE_CODE (gnu_type) == RECORD_TYPE + || TREE_CODE (gnu_type) == UNION_TYPE + || TREE_CODE (gnu_type) == QUAL_UNION_TYPE) + && !TYPE_IS_FAT_POINTER_P (gnu_type)) + size = rm_size (gnu_type); + else + size = TYPE_SIZE (gnu_type); + + /* Consider an alignment as suspicious if the alignment/size + ratio is greater or equal to the byte/bit ratio. */ + if (host_integerp (size, 1) + && align >= TREE_INT_CST_LOW (size) * BITS_PER_UNIT) + post_error_ne ("?suspiciously large alignment specified for&", + Expression (Alignment_Clause (gnat_entity)), + gnat_entity); + } + } else if (Is_Atomic (gnat_entity) && !gnu_size && host_integerp (TYPE_SIZE (gnu_type), 1) && integer_pow2p (TYPE_SIZE (gnu_type))) @@ -6904,25 +6934,25 @@ make_type_from_size (tree type, tree size_tree, bool biased_p) static unsigned int validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align) { - Node_Id gnat_error_node = gnat_entity; - unsigned int new_align; - unsigned int max_allowed_alignment = get_target_maximum_allowed_alignment (); - - if (Present (Alignment_Clause (gnat_entity))) - gnat_error_node = Expression (Alignment_Clause (gnat_entity)); + unsigned int new_align; + Node_Id gnat_error_node; /* Don't worry about checking alignment if alignment was not specified by the source program and we already posted an error for this entity. */ - if (Error_Posted (gnat_entity) && !Has_Alignment_Clause (gnat_entity)) return align; + /* Post the error on the alignment clause if any. */ + if (Present (Alignment_Clause (gnat_entity))) + gnat_error_node = Expression (Alignment_Clause (gnat_entity)); + else + gnat_error_node = gnat_entity; + /* Within GCC, an alignment is an integer, so we must make sure a value is specified that fits in that range. Also, there is an upper bound to alignments we can support/allow. */ - - if (! UI_Is_In_Int_Range (alignment) + if (!UI_Is_In_Int_Range (alignment) || ((new_align = UI_To_Int (alignment)) > max_allowed_alignment)) post_error_ne_num ("largest supported alignment for& is ^", gnat_error_node, gnat_entity, max_allowed_alignment); @@ -6933,7 +6963,11 @@ validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align) gnat_error_node, gnat_entity, align / BITS_PER_UNIT); else - align = MAX (align, new_align == 0 ? 1 : new_align * BITS_PER_UNIT); + { + new_align = (new_align > 0 ? new_align * BITS_PER_UNIT : 1); + if (new_align > align) + align = new_align; + } return align; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a5302d2486..5a6735d7df4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-03-07 Eric Botcazou + + * gnat.dg/specs/alignment2.ads: New test. + 2008-03-07 Eric Botcazou * gnat.dg/pack3.adb: New test. diff --git a/gcc/testsuite/gnat.dg/specs/alignment2.ads b/gcc/testsuite/gnat.dg/specs/alignment2.ads new file mode 100644 index 00000000000..1b92000d2d3 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/alignment2.ads @@ -0,0 +1,45 @@ +with Interfaces; use Interfaces; + +package Alignment2 is + + -- warning + type R1 is record + A, B, C, D : Integer_8; + end record; + for R1'Size use 32; + for R1'Alignment use 32; -- { dg-warning "suspiciously large alignment" } + + -- warning + type R2 is record + A, B, C, D : Integer_8; + end record; + for R2'Alignment use 32; -- { dg-warning "suspiciously large alignment" } + + -- OK, big size + type R3 is record + A, B, C, D : Integer_8; + end record; + for R3'Size use 32 * 8; + for R3'Alignment use 32; + + -- OK, big size + type R4 is record + A, B, C, D, E, F, G, H : Integer_32; + end record; + for R4'Alignment use 32; + + -- warning + type I1 is new Integer_32; + for I1'Size use 32; + for I1'Alignment use 32; -- { dg-warning "suspiciously large alignment" } + + -- warning + type I2 is new Integer_32; + for I2'Alignment use 32; -- { dg-warning "suspiciously large alignment" } + + -- OK, big size + type I3 is new Integer_32; + for I3'Size use 32 * 8; + for I3'Alignment use 32; + +end Alignment2;