From: Guillermo E. Martinez Date: Thu, 17 Nov 2022 03:43:04 +0000 (-0600) Subject: ctf-reader: Fix representation of multidimensional arrays X-Git-Tag: upstream/2.3~111 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e33a74fb8c096bc190704402983acfeca25fc3ee;p=platform%2Fupstream%2Flibabigail.git ctf-reader: Fix representation of multidimensional arrays To build an IR for multidimensional array the CTF front-end iterates over the element types recursively. So, consider the array definition: char a[2][3][4][5]; It's represented as 'char[2][3][4] a[5]' instead of: 'char a[2][3][4][5]' It always considers multidimensional arrays as unidimensional creating a `array-type-def' node for each dimension: ... Instead of: ... Fixed thus. * src/abg-ctf-reader.cc (+build_array_ctf_range): New definition. * tests/data/Makefile.am: Add new testcase. * tests/data/test-read-ctf/test-array-mdimension.abi: New testcase. * tests/data/test-read-ctf/test-array-mdimension.c: Likewise. * tests/data/test-read-ctf/test-array-mdimension.o: Likewise. * tests/data/test-read-ctf/test9.o.abi: Adjust. * tests/test-read-ctf.cc: Update testsuite. Signed-off-by: Guillermo E. Martinez Signed-off-by: Dodji Seketeli --- diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index c48e61a4..b4b957d2 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc @@ -1163,6 +1163,57 @@ process_ctf_union_type(reader *rdr, return result; } +/// Build and return an array subrange. +/// +/// @param rdr the read context. +/// +/// @param ctf_dictionary the CTF dictionary where @ref index +/// will be found. +/// +/// @param index the CTF type ID for the array index. +/// +/// @param nelems the elements number of the array. +/// +/// @return a shared pointer to subrange built. +static array_type_def::subrange_sptr +build_array_ctf_range(reader *rdr, ctf_dict_t *dic, + ctf_id_t index, uint64_t nelems) +{ + bool is_infinite = false; + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); + array_type_def::subrange_sptr subrange; + array_type_def::subrange_type::bound_value lower_bound; + array_type_def::subrange_type::bound_value upper_bound; + + type_base_sptr index_type = rdr->build_type(dic, index); + if (!index_type) + return nullptr; + + lower_bound.set_unsigned(0); /* CTF supports C only. */ + upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U); + + /* for VLAs number of array elements is 0 */ + if (upper_bound.get_unsigned_value() == 0) + is_infinite = true; + + subrange.reset(new array_type_def::subrange_type(rdr->env(), + "", + lower_bound, + upper_bound, + index_type, + location(), + translation_unit::LANG_C)); + if (!subrange) + return nullptr; + + subrange->is_infinite(is_infinite); + add_decl_to_scope(subrange, tunit->get_global_scope()); + canonicalize(subrange); + + return subrange; +} + /// Build and return an array type libabigail IR. /// /// @param rdr the read context. @@ -1181,7 +1232,6 @@ process_ctf_array_type(reader *rdr, translation_unit_sptr tunit = rdr->cur_transl_unit(); array_type_def_sptr result; ctf_arinfo_t ctf_ainfo; - bool is_infinite = false; /* First, get the information about the CTF array. */ if (static_cast(ctf_array_info(ctf_dictionary, @@ -1192,6 +1242,26 @@ process_ctf_array_type(reader *rdr, ctf_id_t ctf_element_type = ctf_ainfo.ctr_contents; ctf_id_t ctf_index_type = ctf_ainfo.ctr_index; uint64_t nelems = ctf_ainfo.ctr_nelems; + array_type_def::subrange_sptr subrange; + array_type_def::subranges_type subranges; + + int type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type); + while (type_array_kind == CTF_K_ARRAY) + { + if (static_cast(ctf_array_info(ctf_dictionary, + ctf_element_type, + &ctf_ainfo)) == CTF_ERR) + return result; + + subrange = build_array_ctf_range(rdr, ctf_dictionary, + ctf_ainfo.ctr_index, + ctf_ainfo.ctr_nelems); + subranges.push_back(subrange); + ctf_element_type = ctf_ainfo.ctr_contents; + type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type); + } + + std::reverse(subranges.begin(), subranges.end()); /* Make sure the element type is generated. */ type_base_sptr element_type = rdr->build_type(ctf_dictionary, @@ -1210,33 +1280,8 @@ process_ctf_array_type(reader *rdr, if (result) return result; - /* The number of elements of the array determines the IR subranges - type to build. */ - array_type_def::subranges_type subranges; - array_type_def::subrange_sptr subrange; - array_type_def::subrange_type::bound_value lower_bound; - array_type_def::subrange_type::bound_value upper_bound; - - lower_bound.set_unsigned(0); /* CTF supports C only. */ - upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U); - - /* for VLAs number of array elements is 0 */ - if (upper_bound.get_unsigned_value() == 0) - is_infinite = true; - - subrange.reset(new array_type_def::subrange_type(rdr->env(), - "", - lower_bound, - upper_bound, - index_type, - location(), - translation_unit::LANG_C)); - if (!subrange) - return result; - - subrange->is_infinite(is_infinite); - add_decl_to_scope(subrange, tunit->get_global_scope()); - canonicalize(subrange); + subrange = build_array_ctf_range(rdr, ctf_dictionary, + ctf_index_type, nelems); subranges.push_back(subrange); /* Finally build the IR for the array type and return it. */ diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 8d4a2b8f..d04ecf3f 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -713,6 +713,9 @@ test-read-ctf/test-bitfield-enum.o \ test-read-ctf/test-const-array.abi \ test-read-ctf/test-const-array.c \ test-read-ctf/test-const-array.o \ +test-read-ctf/test-array-mdimension.abi \ +test-read-ctf/test-array-mdimension.c \ +test-read-ctf/test-array-mdimension.o \ \ test-annotate/test0.abi \ test-annotate/test1.abi \ diff --git a/tests/data/test-read-ctf/test-array-mdimension.abi b/tests/data/test-read-ctf/test-array-mdimension.abi new file mode 100644 index 00000000..177284d2 --- /dev/null +++ b/tests/data/test-read-ctf/test-array-mdimension.abi @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-array-mdimension.c b/tests/data/test-read-ctf/test-array-mdimension.c new file mode 100644 index 00000000..317fc589 --- /dev/null +++ b/tests/data/test-read-ctf/test-array-mdimension.c @@ -0,0 +1,2 @@ +/* gcc -gctf -c test-array-mdimension.c -o test-array-mdimension.o */ +char a[2][3][4][5]; diff --git a/tests/data/test-read-ctf/test-array-mdimension.o b/tests/data/test-read-ctf/test-array-mdimension.o new file mode 100644 index 00000000..5b392d89 Binary files /dev/null and b/tests/data/test-read-ctf/test-array-mdimension.o differ diff --git a/tests/data/test-read-ctf/test9.o.abi b/tests/data/test-read-ctf/test9.o.abi index 331bfc70..9f5a7466 100644 --- a/tests/data/test-read-ctf/test9.o.abi +++ b/tests/data/test-read-ctf/test9.o.abi @@ -11,47 +11,45 @@ - + + - - + + + - - - + + - - - - + - + - + - + - + - + - - + + - - + + diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index f2d529e2..f3d46118 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc @@ -372,6 +372,15 @@ static InOutSpec in_out_specs[] = "output/test-read-ctf/test-const-array.abi", "--ctf", }, + { + "data/test-read-ctf/test-array-mdimension.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-ctf/test-array-mdimension.abi", + "output/test-read-ctf/test-array-mdimension.abi", + "--ctf", + }, // This should be the last entry. {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL} };