From: Tom Tromey Date: Thu, 7 May 2026 18:08:40 +0000 (-0600) Subject: Handle DW_AT_encoding on DW_TAG_enumeration_type X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=ebc3d2cc69d62103a08a4fbf90d36dfdd6743d9b;p=thirdparty%2Fbinutils-gdb.git Handle DW_AT_encoding on DW_TAG_enumeration_type A user pointed out a problem when printing certain values from an Ada enumeration type. Investigation showed that the problem was that some enumeration constants were emitted using DW_FORM_data1, and were incorrectly sign-extended by gdb. First, this is yet another instance of a general problem with DWARF. See https://sourceware.org/bugzilla/show_bug.cgi?id=32680 for the analysis. Meanwhile, it turns out that GCC implements an extension to handle this scenario. In particular, in non-strict mode, it will emit DW_AT_encoding using either DW_ATE_signed or DW_ATE_unsigned. This was done back in 2017 by Pierre-Marie, in support of Ada -- but then somehow nothing was ever implemented on the gdb side. For this see GCC commit f76f096e ("DWARF: add DW_AT_encoding attributes for DW_TAG_enumeration_type DIEs"). This patch adds the missing code to gdb. The included test case shows the bug that was originally reported. I've also included the snippet from Pierre-Marie's commit message for good measure. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32680 Approved-By: Andrew Burgess --- diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 4d8923d3ca7..f8ade564b0b 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -11024,6 +11024,22 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) set_type_align (type, TYPE_RAW_ALIGN (underlying_type)); } + /* DW_AT_encoding on an enumeration type is a GCC extension. GCC + will only emit DW_ATE_signed or DW_ATE_unsigned here. If this is + seen, it provides a way to find the signed-ness without having to + guess based on the constants, which is somewhat fraught anyway + (see PR symtab/32680). */ + if (!is_unsigned.has_value ()) + { + attribute *encoding_attr = dwarf2_attr (die, DW_AT_encoding, cu); + if (encoding_attr != nullptr) + { + std::optional val = encoding_attr->unsigned_constant (); + if (val.has_value ()) + is_unsigned = *val == DW_ATE_unsigned; + } + } + type->set_is_declared_class (dwarf2_flag_true_p (die, DW_AT_enum_class, cu)); type->set_endianity_is_not_default (die_byte_order (die, cu, nullptr)); diff --git a/gdb/testsuite/gdb.ada/enum-sign.exp b/gdb/testsuite/gdb.ada/enum-sign.exp new file mode 100644 index 00000000000..84098027849 --- /dev/null +++ b/gdb/testsuite/gdb.ada/enum-sign.exp @@ -0,0 +1,40 @@ +# Copyright 2026 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile prog + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != ""} { + return +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/prog.adb] +runto "prog.adb:$bp_location" + +for {set num 0} {$num <= 300} {incr num} { + gdb_test "print Value_$num" " = value_$num" + gdb_test "print Unsigned_Enumeration'Val($num)" " = value_$num" + gdb_test "print/d Unsigned_Enumeration'Val($num)" " = $num" +} + +foreach {name dec} {se_a -1 se_b 0 se_c 1 se_d 2} { + gdb_test "print $name" " = $name" + gdb_test "print/d $name" " = $dec" +} diff --git a/gdb/testsuite/gdb.ada/enum-sign/prog.adb b/gdb/testsuite/gdb.ada/enum-sign/prog.adb new file mode 100644 index 00000000000..6ef3c956917 --- /dev/null +++ b/gdb/testsuite/gdb.ada/enum-sign/prog.adb @@ -0,0 +1,331 @@ +-- Copyright 2026 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +procedure Prog is + type Unsigned_Enumeration is + ( + Value_0, + Value_1, + Value_2, + Value_3, + Value_4, + Value_5, + Value_6, + Value_7, + Value_8, + Value_9, + Value_10, + Value_11, + Value_12, + Value_13, + Value_14, + Value_15, + Value_16, + Value_17, + Value_18, + Value_19, + Value_20, + Value_21, + Value_22, + Value_23, + Value_24, + Value_25, + Value_26, + Value_27, + Value_28, + Value_29, + Value_30, + Value_31, + Value_32, + Value_33, + Value_34, + Value_35, + Value_36, + Value_37, + Value_38, + Value_39, + Value_40, + Value_41, + Value_42, + Value_43, + Value_44, + Value_45, + Value_46, + Value_47, + Value_48, + Value_49, + Value_50, + Value_51, + Value_52, + Value_53, + Value_54, + Value_55, + Value_56, + Value_57, + Value_58, + Value_59, + Value_60, + Value_61, + Value_62, + Value_63, + Value_64, + Value_65, + Value_66, + Value_67, + Value_68, + Value_69, + Value_70, + Value_71, + Value_72, + Value_73, + Value_74, + Value_75, + Value_76, + Value_77, + Value_78, + Value_79, + Value_80, + Value_81, + Value_82, + Value_83, + Value_84, + Value_85, + Value_86, + Value_87, + Value_88, + Value_89, + Value_90, + Value_91, + Value_92, + Value_93, + Value_94, + Value_95, + Value_96, + Value_97, + Value_98, + Value_99, + Value_100, + Value_101, + Value_102, + Value_103, + Value_104, + Value_105, + Value_106, + Value_107, + Value_108, + Value_109, + Value_110, + Value_111, + Value_112, + Value_113, + Value_114, + Value_115, + Value_116, + Value_117, + Value_118, + Value_119, + Value_120, + Value_121, + Value_122, + Value_123, + Value_124, + Value_125, + Value_126, + Value_127, + Value_128, + Value_129, + Value_130, + Value_131, + Value_132, + Value_133, + Value_134, + Value_135, + Value_136, + Value_137, + Value_138, + Value_139, + Value_140, + Value_141, + Value_142, + Value_143, + Value_144, + Value_145, + Value_146, + Value_147, + Value_148, + Value_149, + Value_150, + Value_151, + Value_152, + Value_153, + Value_154, + Value_155, + Value_156, + Value_157, + Value_158, + Value_159, + Value_160, + Value_161, + Value_162, + Value_163, + Value_164, + Value_165, + Value_166, + Value_167, + Value_168, + Value_169, + Value_170, + Value_171, + Value_172, + Value_173, + Value_174, + Value_175, + Value_176, + Value_177, + Value_178, + Value_179, + Value_180, + Value_181, + Value_182, + Value_183, + Value_184, + Value_185, + Value_186, + Value_187, + Value_188, + Value_189, + Value_190, + Value_191, + Value_192, + Value_193, + Value_194, + Value_195, + Value_196, + Value_197, + Value_198, + Value_199, + Value_200, + Value_201, + Value_202, + Value_203, + Value_204, + Value_205, + Value_206, + Value_207, + Value_208, + Value_209, + Value_210, + Value_211, + Value_212, + Value_213, + Value_214, + Value_215, + Value_216, + Value_217, + Value_218, + Value_219, + Value_220, + Value_221, + Value_222, + Value_223, + Value_224, + Value_225, + Value_226, + Value_227, + Value_228, + Value_229, + Value_230, + Value_231, + Value_232, + Value_233, + Value_234, + Value_235, + Value_236, + Value_237, + Value_238, + Value_239, + Value_240, + Value_241, + Value_242, + Value_243, + Value_244, + Value_245, + Value_246, + Value_247, + Value_248, + Value_249, + Value_250, + Value_251, + Value_252, + Value_253, + Value_254, + Value_255, + Value_256, + Value_257, + Value_258, + Value_259, + Value_260, + Value_261, + Value_262, + Value_263, + Value_264, + Value_265, + Value_266, + Value_267, + Value_268, + Value_269, + Value_270, + Value_271, + Value_272, + Value_273, + Value_274, + Value_275, + Value_276, + Value_277, + Value_278, + Value_279, + Value_280, + Value_281, + Value_282, + Value_283, + Value_284, + Value_285, + Value_286, + Value_287, + Value_288, + Value_289, + Value_290, + Value_291, + Value_292, + Value_293, + Value_294, + Value_295, + Value_296, + Value_297, + Value_298, + Value_299, + Value_300 + ); + + X : Unsigned_Enumeration := Value_23; + + type Signed_Enumeration is ( SE_A, SE_B, SE_C, SE_D); + for Signed_Enumeration use (-1, 0, 1, 2); + + Y : Signed_Enumeration := SE_D; + +begin + null; -- STOP +end;