https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104194
Bug ID: 104194 Summary: No way to distinguish IEEE and IBM long double in debug info Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- With a simple: long double foo (long double x) { return x; } long double a; and compiling with both -g -O2 -dA -mabi=ibmlongdouble and -g -O2 -dA -mabi=ieeelongdouble shows the same .uleb128 0x3 # (DIE (0x42) DW_TAG_base_type) .byte 0x10 # DW_AT_byte_size .byte 0x4 # DW_AT_encoding .4byte .LASF2 # DW_AT_name: "long double" base type being used in both cases, yes, there are 2 16 byte type DW_ATE_floating types, but guess the debugger needs to differentiate between the two, because how else would it know how to decode the bits? It is true that without -mno-gnu-attributes .gnu.attributes is produced, but with -mno-gnu-attributes it isn't, and e.g. elfutils eu-strip strips .gnu.attributes into a separate section. Also relying on DW_AT_producer doesn't work well, because the -mabi= option can have configured in different defaults. On the above testcase there is a small difference: .uleb128 0x5 # (DIE (0x67) DW_TAG_formal_parameter) .ascii "x\0" # DW_AT_name .byte 0x1 # DW_AT_decl_file (a.c) .byte 0x1 # DW_AT_decl_line .byte 0x1e # DW_AT_decl_column .4byte 0x42 # DW_AT_type - .uleb128 0x8 # DW_AT_location + .uleb128 0x2 # DW_AT_location .byte 0x90 # DW_OP_regx - .uleb128 0x21 - .byte 0x93 # DW_OP_piece - .uleb128 0x8 - .byte 0x90 # DW_OP_regx - .uleb128 0x22 - .byte 0x93 # DW_OP_piece - .uleb128 0x8 + .uleb128 0x4f but that just says that the x argument lives in a different location, not all long double parameters are passed in registers and so there is no way to distinguish those, similarly there is no way to distinguish automatic or static variables or function return types. I'm actually not sure what we should do, whether some new GNU attribute in addition to the current DW_TAG_base_type attributes, or using some user DW_ATE_ value (pedantically DW_ATE_float is correct for both), DW_AT_digit_count is for decimal. Note, there are HP extensions: /* HP extensions. */ DW_ATE (DW_ATE_HP_float80, 0x80) /* Floating-point (80 bit). */ DW_ATE (DW_ATE_HP_complex_float80, 0x81) /* Complex floating-point (80 bit). */ DW_ATE (DW_ATE_HP_float128, 0x82) /* Floating-point (128 bit). */ DW_ATE (DW_ATE_HP_complex_float128, 0x83) /* Complex fp (128 bit). */ DW_ATE (DW_ATE_HP_floathpintel, 0x84) /* Floating-point (82 bit IA64). */ DW_ATE (DW_ATE_HP_imaginary_float80, 0x85) DW_ATE (DW_ATE_HP_imaginary_float128, 0x86) DW_ATE (DW_ATE_HP_VAX_float, 0x88) /* F or G floating. */ DW_ATE (DW_ATE_HP_VAX_float_d, 0x89) /* D floating. */ DW_ATE (DW_ATE_HP_packed_decimal, 0x8a) /* Cobol. */ DW_ATE (DW_ATE_HP_zoned_decimal, 0x8b) /* Cobol. */ DW_ATE (DW_ATE_HP_edited, 0x8c) /* Cobol. */ DW_ATE (DW_ATE_HP_signed_fixed, 0x8d) /* Cobol. */ DW_ATE (DW_ATE_HP_unsigned_fixed, 0x8e) /* Cobol. */ DW_ATE (DW_ATE_HP_VAX_complex_float, 0x8f) /* F or G floating complex. */ DW_ATE (DW_ATE_HP_VAX_complex_float_d, 0x90) /* D floating complex. */ but e.g. we use DW_ATE_lo_user aka 0x80 for complex int.