diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 091ba237370..70d7cd64e08 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2018-06-12 Eric Botcazou + + * gcc-interface/decl.c (warn_on_field_placement): Use specific wording + for discriminants. + (warn_on_list_placement): New static function. + (components_to_record): Use it to warn on multiple fields in list. + 2018-06-12 Eric Botcazou * gcc-interface/decl.c (variant_desc): Add AUX field. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index a79cb007024..ddc48d9b8cb 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -7296,31 +7296,44 @@ warn_on_field_placement (tree gnu_field, Node_Id gnat_component_list, if (!Comes_From_Source (gnat_record_type)) return; + Entity_Id gnat_field + = gnu_field_to_gnat (gnu_field, gnat_component_list, gnat_record_type); + gcc_assert (Present (gnat_field)); + const char *msg1 = in_variant ? "?variant layout may cause performance issues" : "?record layout may cause performance issues"; const char *msg2 - = field_has_self_size (gnu_field) - ? "?component & whose length depends on a discriminant" - : field_has_variable_size (gnu_field) - ? "?component & whose length is not fixed" - : "?component & whose length is not multiple of a byte"; + = Ekind (gnat_field) == E_Discriminant + ? "?discriminant & whose length is not multiple of a byte" + : field_has_self_size (gnu_field) + ? "?component & whose length depends on a discriminant" + : field_has_variable_size (gnu_field) + ? "?component & whose length is not fixed" + : "?component & whose length is not multiple of a byte"; const char *msg3 = do_reorder ? "?comes too early and was moved down" : "?comes too early and ought to be moved down"; - Entity_Id gnat_field - = gnu_field_to_gnat (gnu_field, gnat_component_list, gnat_record_type); - - gcc_assert (Present (gnat_field)); - post_error (msg1, gnat_field); post_error_ne (msg2, gnat_field, gnat_field); post_error (msg3, gnat_field); } +/* Likewise but for every field present on GNU_FIELD_LIST. */ + +static void +warn_on_list_placement (tree gnu_field_list, Node_Id gnat_component_list, + Entity_Id gnat_record_type, bool in_variant, + bool do_reorder) +{ + for (tree gnu_tmp = gnu_field_list; gnu_tmp; gnu_tmp = DECL_CHAIN (gnu_tmp)) + warn_on_field_placement (gnu_tmp, gnat_component_list, gnat_record_type, + in_variant, do_reorder); +} + /* Structure holding information for a given variant. */ typedef struct vinfo { @@ -7895,11 +7908,18 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type, if (tmp_bitp_size != 0) { if (w_reorder && tmp_last_reorder_field_type < 2) - warn_on_field_placement (gnu_tmp_bitp_list - ? gnu_tmp_bitp_list : gnu_last, - gnat_component_list, - gnat_record_type, in_variant, - do_reorder); + { + if (gnu_tmp_bitp_list) + warn_on_list_placement (gnu_tmp_bitp_list, + gnat_component_list, + gnat_record_type, in_variant, + do_reorder); + else + warn_on_field_placement (gnu_last, + gnat_component_list, + gnat_record_type, in_variant, + do_reorder); + } if (do_reorder) gnu_bitp_list = chainon (gnu_tmp_bitp_list, gnu_bitp_list); @@ -7953,10 +7973,16 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type, if (last_reorder_field_type == 2 && tmp_bitp_size != 0 && tmp_last_reorder_field_type < 2) - warn_on_field_placement (gnu_tmp_bitp_list - ? gnu_tmp_bitp_list : gnu_field_list, - gnat_component_list, gnat_record_type, - in_variant, do_reorder); + { + if (gnu_tmp_bitp_list) + warn_on_list_placement (gnu_tmp_bitp_list, + gnat_component_list, gnat_record_type, + in_variant, do_reorder); + else + warn_on_field_placement (gnu_field_list, + gnat_component_list, gnat_record_type, + in_variant, do_reorder); + } } if (do_reorder)