[Bug debug/94474] New: Incorrect DWARF range information for inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 Bug ID: 94474 Summary: Incorrect DWARF range information for inlined function Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: andrew.burgess at embecosm dot com Target Milestone: --- Created attachment 48190 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48190&action=edit Bug reproducer. Download the attached file, then: tar -xf gcc-ranges-bugs.tar.xz cd gcc-ranges-bugs make The problem is described in the included README file, the contents of which I will include below. -- * Overview + The issues are present in all compilations, but v3 uses what I think might be the "best" debug flags. + Tested on GCC 9.2.0 and GCC from master branch (2020-02-05). + These bugs were encountered when trying to improve is-stmt support within GDB. + This bug report has a bit of history. Originally there was a GCC patch here: https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01459.html and a reply here: https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01459.html This led to a GDB patch here: https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01459.html which in turn led to a different GDB patch (adding is-stmt support), here: https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01459.html + As suggested in the 2019-10 GCC follow up, I have tried compiling with =-gno-statement-frontiers -gno-variable-location-views=, and currently the debug experience is better, but if I hack GDB to "fix" the bugs below while reading in the DWARF then I get just as good a debug experience with GCC's default flags. + In the included Makefile I build the test 4 times, version 3 is possibly the most interesting, as this explicitly switches on what I think are the "best" features for location tracking. However, the same bugs are present in v1 and v2 (see Makefile for flag differences). Version 4 compiles with the =-gno-*= flags above, and is included for reference. As I've already said, these bugs are not present there. + All of the analysis below references the output files =test-v3=, =dissas-v3=, =dwarf-v3=, and =lines-v3=. * Issue 1 + The function =tree_check= is inlined 3 times. + The first =DW_TAG_inlined_subroutine= looks like this: #+BEGIN_EXAMPLE <2><8db>: Abbrev Number: 38 (DW_TAG_inlined_subroutine) <8dc> DW_AT_abstract_origin: <0x9cc> <8e0> DW_AT_entry_pc: 0x400545 <8e8> Unknown AT value: 2138: 3 <8e9> DW_AT_ranges : 0x30 <8ed> DW_AT_call_file : 1 <8ee> DW_AT_call_line : 52 <8ef> DW_AT_call_column : 10 <8f0> DW_AT_sibling : <0x92f> #+END_EXAMPLE This references some =.debug_ranges= data that looks like this: #+BEGIN_EXAMPLE 0030 00400545 00400545 (start == end) 0030 00400549 00400553 0030 00400430 00400435 0030 #+END_EXAMPLE + Notice that =0x400545= is /not/ part of the range for the inlined function as the range ==0x400545= to =0x400545= is an empty range, containing no bytes (see DWARF-4, 2.17.3: Non-Contiguous Address Ranges). + The =DW_AT_entry_pc= points to =0x400545=. + DWARF-4, 2.18: Entry Address, says: #+BEGIN_QUOTE Any debugging information entry describing an entity that has a range of code addresses, which includes compilation units, module initialization, subroutines, ordinary blocks, try/catch blocks, and the like, may have a DW_AT_entry_pc attribute to indicate the first executable instruction within that range of addresses. #+END_QUOTE I believe this means that the =DW_AT_entry_pc= should reference an address that is within the range of addresses associated with the inlined subroutine. + The particular problem this causes for GDB is that the decoded line table (see =lines-v3=) includes: #+BEGIN_EXAMPLE ./step-and-next-inline.h:[++] step-and-next-inline.h320x400545 3 x step-and-next-inline.h340x400545 4 x #+END_EXAMPLE GDB then stops for these lines (that are part of the inlined function, at an address that is not part of the inlined functions address range. + An idea solution for GDB would be to include the address =0x400545= within the address range of the inlined function, and when I earlier said I hacked GDB to "fix" this bug, this is what I did,
[Bug debug/94474] Incorrect DWARF range information for inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 --- Comment #2 from Andrew Burgess --- Sorry for including the wrong DWARF dump output in the bug report. I too had seen the DW_AT_GNU_entry_view using a more recent binutils. When you pose the question: I am not sure if there are any view numbers when the inline has multiple ranges, (I dont remember) I think you're asking do we get DW_AT_GNU_entry_view when we have multiple ranges. And the answer is yes, this case already has multiple ranges (it has a DW_AT_ranges, which contains multiple ranges), and this is super confusing, because each range could, I guess, could have a different view number for its start, right? It seems that, when a debug entity has a single range defined within the entity then we need a start and end view number. When a debug entity makes use of separate range information, each range will need its own start and end view number. If the above requires new DWARF extensions, then GCC might just decide to try and make the best with the version of DWARF it currently has available.
[Bug debug/94474] Incorrect DWARF range information for inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 --- Comment #5 from Andrew Burgess --- Bernd, Wouldn't DW_AT_GNU_exit_view be attached to the DW_TAG_inlined_subroutine though? So, as in this case, one subroutine has 2 ranges, but would then have one end view number. I don't understand why each range wouldn't need its own view number?
[Bug debug/94474] Incorrect DWARF range information for inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 --- Comment #8 from Andrew Burgess --- Bernd, Please could you keep discussion of GDB patches to the GDB mailing list unless it is required to move this bug forward. In this bug I make the claim that the DWARF GCC produces is not correct. So far I don't think you are disagreeing with that. You are, I think, proposing that we should add range end view numbers to the range table. I'm not disagreeing that this would solve the problem. However, Right now I don't think such a feature is currently in the DWARF standard, maybe it exists as part of a DWARF proposal? Or maybe as a GCC extension? I don't know. The question I'm asking to the wider GCC community would be, given the (I claim) current incorrect DWARF, should GCC be changed to produce something better using existing standard DWARF? Should a new GCC DWARF extension be invented? I certainly don't claim to have the answer here, but hopefully someone else might have a concrete proposal.
[Bug debug/94474] Incorrect DWARF range information for inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 --- Comment #10 from Andrew Burgess --- Bernd, Not a problem, always happy to expand on things. This might get a little long, but hopefully it should give you an idea what I think is wrong. I have not updated the reproducer, I don't know why I would need to do that, as the existing example demonstrates the issues. My original comment did use an older version of binutils though, which is why I saw =<8e8> Unknown AT value: 2138: 3=, which was unfortunate. I'm now using binutils 2.34. To reduce the length of this post I'm only looking at the first inlined subroutine, this is the worst offender, the issues with the other two are just repeats of this one. >From the reproducer I'm only looking at the *-v3 output files. Here's the DWARF for the first inlined subroutine: #+BEGIN_EXAMPLE <2><8dd>: Abbrev Number: 38 (DW_TAG_inlined_subroutine) <8de> DW_AT_abstract_origin: <0x9ce> <8e2> DW_AT_entry_pc: 0x401165 <8ea> DW_AT_GNU_entry_view: 0 <8eb> DW_AT_ranges : 0x30 <8ef> DW_AT_call_file : 1 <8f0> DW_AT_call_line : 52 <8f1> DW_AT_call_column : 10 <8f2> DW_AT_sibling : <0x931> #+END_EXAMPLE It references the range information at offset 0x30, which can be seen here, the duplication is just an objdump oddity, the ranges we care about are the first four lines starting with =0030=: #+BEGIN_EXAMPLE Contents of the .debug_ranges section: Offset BeginEnd 00401160 004011ca 00401040 00401045 0030 00401165 00401165 (start == end) 0030 00401169 00401173 0030 00401040 00401045 0030 0030 00401165 00401165 (start == end) 0030 00401169 00401173 0030 00401040 00401045 0030 0070 00401160 004011ca 0070 00401040 00401045 0070 00401050 00401065 0070 #+END_EXAMPLE Next, here's a snippet of disassembler, this covers two of the ranges from the above, the empty one =0x401165= to =0x401165=, and then =0x401169= to =0x401173=. The range =0x401040= to =0x401045= I'm ignoring for now, it's just some out of line cold code and not important for this discussion: #+BEGIN_EXAMPLE 00401160 <_Z13get_alias_setP4tree>: 401160: 48 85 fftest %rdi,%rdi 401163: 74 4b je 4011b0 <_Z13get_alias_setP4tree+0x50> 401165: 48 83 ec 08 sub$0x8,%rsp 401169: 8b 07 mov(%rdi),%eax 40116b: 85 c0 test %eax,%eax 40116d: 0f 85 cd fe ff ff jne401040 <_Z13get_alias_setP4tree.cold> 401173: 8b 47 04mov0x4(%rdi),%eax 401176: 83 f8 01cmp$0x1,%eax 401179: 74 28 je 4011a3 <_Z13get_alias_setP4tree+0x43> 40117b: 8b 07 mov(%rdi),%eax 40117d: 85 c0 test %eax,%eax #+END_EXAMPLE Finally, a snippet of the line table covering the same disassembler region as above: #+BEGIN_EXAMPLE test-v3: file format elf64-x86-64 Contents of the .debug_line section: CU: ./step-and-next-inline.cc: File nameLine numberStarting addressView Stmt step-and-next-inline.cc 500x401160 x step-and-next-inline.cc 510x401160 1 x step-and-next-inline.cc 540x401160 2 ./step-and-next-inline.h:[++] step-and-next-inline.h320x401165 x step-and-next-inline.h340x401165 1 x ./step-and-next-inline.cc:[++] step-and-next-inline.cc 500x401165 2 ./step-and-next-inline.h:[++] step-and-next-inline.h340x401169 step-and-next-inline.h340x40116b step-and-next-inline.h360x401173 x step-and-next-inline.h370x401173 1 x step-and-next-inline.h370x401173 2 ./step-and-next-inline.cc:[++] step-and-next-inline.cc 520x401173 3 step-and-next-inline.cc 520x401176 #+END_EXAMPLE Here is what I think GCC could have produced for the range information instead: #+BEGIN_EXAMPLE 0030 00401165 00401176 0030 00401040 00401045 0
[Bug debug/94474] Incorrect DWARF range information for inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 --- Comment #12 from Andrew Burgess --- > But what I learned from writing the patch is that gcc cannot > easily tell if a range will be empty or not. That is because > the assembler does emit the line info and the views, > and the assembler decides how many bytes if any a certain > construct will take in the binary representation. > > That is why this empty range appears, because that was > supposed to be the start of the inline function, but > instructions from the function prologue were moved in there. I think there's some miss-communication here. In the first paragraph you say the assembler is responsible for deciding the binary representation. I'd agree with that, in the GNU toolchain this is gas. Then in the second paragraph you say the assembler is performing instruction reordering. Now I don't know every gas optimisation, so I'm not saying gas doesn't do that, but it's not common, and it certainly isn't what's happening in this case. The instruction motion is entirely within GCC. I'll offer evidence for this below. > What causes the problem is the is-stmt line info which > is the only remaining thing from the original plan. And here in lies the GCC bug (or one of them). GCC has performed instruction motion, and GCC has left behind its marker for the is-stmt line. I make no claim about how easy this is to fix, or if (given GCC's code base) its even reasonably possible to consider fixing it, but that doesn't mean it isn't a GCC issue. > But on the other hand, it is not a big issue for gdb to > ignore those artefacts, when they rarely occur. GDB already ignores empty ranges. The DWARF standard specifically allows empty ranges and states that they are to be ignored. But that isn't the artefact you're talking about, you mean the is-stmt markers. The problem is, the markers are placed at an address, given that every address eventually contains an instruction[1] eventually, how can GDB tell if one marker was left by accident or not? > My gdb-patch does this, by changing the is-stmt bit of > this line info. Yes, and I think with this discussion we are getting closer to understanding the work around you want to introduce to GDB, something along the lines of: - On versions XXX -> YYY of GCC, - An is-stmt true marker, - At the same address as an empty range, that is - Associated with an inline function instance, should - Be ignored. It's this kind of specific identification of the bug you're working around that (for me at least) is holding back your GDB patch. But, we shouldn't make a choice between work around the GCC bug in GDB _or_ fix the bug in GCC. The ideal solution (for me) would be, fix GCC _and_ add a work around into GDB targeting the known broken versions of GCC, then we get the best of both worlds. --- To back up my claim that this is a GCC issue, you can generate the assembler file test-v3.s from the reproducer. The .debug_ranges looks like this: .section.debug_ranges,"",@progbits .Ldebug_ranges0: .quad .LFB21 .quad .LHOTE0 .quad .LFSB21 .quad .LCOLDE0 .quad 0 .quad 0 .quad .LBB8 .quad .LBE8 .quad .LBB12 .quad .LBE12 .quad .LBB17 .quad .LBE17 .quad 0 .quad 0 The empty range is the first range in the second sequence, so this one: .quad .LBB8 .quad .LBE8 If we then find this in the assembler we see: .LBB8: .LBI8: .file 2 "step-and-next-inline.h" .loc 2 32 1 is_stmt 1 view .LVU3 .LBB9: .loc 2 34 3 view .LVU4 .LBE9: .LBE8: .loc 1 50 1 is_stmt 0 view .LVU5 subq$8, %rsp .cfi_def_cfa_offset 16 Notice, no assembler instructions (but there are assembler directives) between LBB8 and LBE8. I agree 100% with your diagnosis that this is likely due to instruction reordering, but I disagree with your analysis that this is done in the assembler and that therefore GCC has no visibility of this. --- [1] I know, not _literally_ every address, but you get the point.
[Bug fortran/92775] New: Incorrect expression in DW_AT_byte_stride on an array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92775 Bug ID: 92775 Summary: Incorrect expression in DW_AT_byte_stride on an array Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: andrew.burgess at embecosm dot com Target Milestone: --- Created attachment 47411 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47411&action=edit Example. 1. Unpack the example, and run 'make'. This creates a test binary called 'test', and the DWARF from that binary is placed into 'test.dwarf'. Initially I'm using GCC 7.4.0. 2. In the generated 'test.dwarf' Find the DW_TAG_variable for 'point_dimension', note its DW_AT_type and DW_AT_location. For me I have: <2>: Abbrev Number: 10 (DW_TAG_variable) DW_AT_name: (indirect string, offset: 0x0): point_dimension DW_AT_decl_file : 1 DW_AT_decl_line : 13 DW_AT_type: <0x18a> DW_AT_location: 9 byte block: 3 80 10 60 0 0 0 0 0 (DW_OP_addr: 601080) ... <1><18a>: Abbrev Number: 16 (DW_TAG_array_type) <18b> DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref) <18e> DW_AT_associated : 4 byte block: 97 6 30 2e (DW_OP_push_object_address; DW_OP_deref; DW_OP_lit0; DW_OP_ne) <193> DW_AT_type: <0x5d> <2><197>: Abbrev Number: 17 (DW_TAG_subrange_type) <198> DW_AT_lower_bound : 4 byte block: 97 23 20 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 32; DW_OP_deref) <19d> DW_AT_upper_bound : 4 byte block: 97 23 28 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 40; DW_OP_deref) <1a2> DW_AT_byte_stride : 15 byte block: 97 23 18 6 3 b0 10 60 0 0 0 0 0 6 1e (DW_OP_push_object_address; DW_OP_plus_uconst: 24; DW_OP_deref; DW_OP_addr: 6010b0; DW_OP_deref; DW_OP_mul) 3. Figure out the expression to read the DW_AT_byte_stride, from the above it will be: ((*(0x601080 + 24)) * (*0x6010b0)) 4. Run the test program, this just confirms what we expect the value of 'point_dimension' to be, which is: { 2, 2, 2, 2, 2, 2, 2, 2, 2 }. 5. Now fire up GDB on the test program: $ gdb test (gdb) break 18 (gdb) run (gdb) p/d ((*(0x601080 + 24)) * (*0x6010b0)) $1 = 24 # So the stride appears to be 24. Now to check, first, where's the # first element: (gdb) p &point_dimension(1) $2 = (PTR TO -> ( integer(kind=8) )) 0x7fffccd8 # Now lets check the stride is correct by examining all the # remaining elements: (gdb) x/1w 0x7fffccd8 + (24 * 0) 0x7fffccd8: 2 (gdb) x/1w 0x7fffccd8 + (24 * 1) 0x7fffccf0: 2 (gdb) x/1w 0x7fffccd8 + (24 * 2) 0x7fffcd08: 2 (gdb) x/1w 0x7fffccd8 + (24 * 3) 0x7fffcd20: 2 (gdb) x/1w 0x7fffccd8 + (24 * 4) 0x7fffcd38: 2 (gdb) x/1w 0x7fffccd8 + (24 * 5) 0x7fffcd50: 2 (gdb) x/1w 0x7fffccd8 + (24 * 6) 0x7fffcd68: 2 (gdb) x/1w 0x7fffccd8 + (24 * 7) 0x7fffcd80: 2 (gdb) x/1w 0x7fffccd8 + (24 * 8) 0x7fffcd98: 2 # So it looks like a stride of 24 is correct. Based on the code # this is what I would expect. 6. Now recompile the test with a later version of GCC. I've tested 8.3.0 and 9.2.0, plus a version from trunk from mid-October 2019. The data below is from 9.2.0: <2>: Abbrev Number: 10 (DW_TAG_variable) DW_AT_name: (indirect string, offset: 0x0): point_dimension DW_AT_decl_file : 1 DW_AT_decl_line : 13 DW_AT_type: <0x10f> DW_AT_location: 9 byte block: 3 80 10 60 0 0 0 0 0 (DW_OP_addr: 601080) ... <1><10f>: Abbrev Number: 13 (DW_TAG_array_type) <110> DW_AT_data_location: 2 byte block: 97 6 (DW_OP_push_object_address; DW_OP_deref) <113> DW_AT_associated : 4 byte block: 97 6 30 2e (DW_OP_push_object_address; DW_OP_deref; DW_OP_lit0; DW_OP_ne) <118> DW_AT_type: <0x5d> <2><11c>: Abbrev Number: 14 (DW_TAG_subrange_type) <11d> DW_AT_lower_bound : 4 byte block: 97 23 30 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 48; DW_OP_deref) <122> DW_AT_upper_bound : 4 byte block: 97 23 38 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 56; DW_OP_deref) <127> DW_AT_byte_stride : 6 byte block: 97 23 28 6 38 1e (DW_OP_push_object_address; DW_OP_plus_uconst: 40; DW_OP_deref; DW_OP_lit8; DW_OP_mul) 7. Notice that the DW_AT_byte_stride expression has changed, it now
[Bug fortran/92775] Incorrect expression in DW_AT_byte_stride on an array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92775 --- Comment #1 from Andrew Burgess --- I ran a bisect and this is the commit where GCC stops producing the DWARF I would expect to see: In GIT: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=47e6a59aedf4b114c2b4865c97a91a7b700cd991 In SVN: https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=251949
[Bug middle-end/86058] New: TARGET_MEM_REF causing incorrect message for -Wmaybe-uninitialized warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86058 Bug ID: 86058 Summary: TARGET_MEM_REF causing incorrect message for -Wmaybe-uninitialized warning Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: andrew.burgess at embecosm dot com Target Milestone: --- The following: /* { dg-do compile } */ /* { dg-options "-O2 -Wuninitialized -Wmaybe-uninitialized" } */ extern void foo (int *); void zip (int *out, int indx) { int arr[10]; for (int i = 0; i < indx; ++i) out[i] = arr[i] + 1; /* { dg-warning "'arr[i]' may be used uninitialized in this function" } */ foo (arr); foo (out); } When compiled gives this warning: $ gcc -Wuninitialized -Wmaybe-uninitialized -O2 test.c #‘target_mem_ref’ not supported by expression#’ test.c: In function ‘zip’: test.c:12:17: warning: may be used uninitialized in this function [-Wmaybe-uninitialized] out[i] = arr[i] + 1; /* { dg-warning "'arr[i]' may be used uninitialized in this function" } */ ~~~^~~ The problem seems to arise from tree-ssa-uninit.c:warn_uninitialized_vars which ends up calling warning_at and using %qE to format a tree, which is of type TRAGET_MEM_REF.
[Bug middle-end/86058] TARGET_MEM_REF causing incorrect message for -Wmaybe-uninitialized warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86058 --- Comment #2 from Andrew Burgess --- Sorry, this is on x86-64/GNU-Linux
[Bug c/70039] New: Data placed into rodata that could be encoded as immediates
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70039 Bug ID: 70039 Summary: Data placed into rodata that could be encoded as immediates Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: andrew.burgess at embecosm dot com Target Milestone: --- Created attachment 37840 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37840&action=edit An example of this behaviour Compiling the attached file with gcc from SVN 1-Mar-2016 on x86-64 GNU/Linux: gcc -O2 -Wall -Wextra -o fill.s -S fill.i Here's some of the source: void fill_from_array (char * d) { static const char a[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', }; memcpy (d, a, 20); } void fill_from_string (char * d) { static const char a[] = "abcdefghijklmnopqrstuvwxyz"; memcpy (d, a, 20); } in the generated assembler of fill_from_string the data is written to the destination pointer (d) as constants, like this: movabsq $7523094288207667809, %rax movl$1953722993, 16(%rdi) movq%rax, (%rdi) movabsq $8101815670912281193, %rax movq%rax, 8(%rdi) However, in the fill_from_array case the array data is held in the .rodata section, loaded, and then stored to the destination. My expectation would have been that the code generated in each case would have been identical.
[Bug testsuite/78544] FAIL: gcc.dg/tree-prof/section-attr-*.c compilation, -fprofile-generate -D_PROFILE_GENERATE on darwin
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78544 --- Comment #1 from Andrew Burgess --- Created attachment 40162 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40162&action=edit Patch to skip the tests As the tests are only going to test anything on a subset of targets, I don't know if we care particularly about having the compile complete on all targets. The attached patch should (if I have the syntax correct) skip the tests on all but the targets that are going to run the test.
[Bug testsuite/78544] FAIL: gcc.dg/tree-prof/section-attr-*.c compilation, -fprofile-generate -D_PROFILE_GENERATE on darwin
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78544 --- Comment #4 from Andrew Burgess --- I only suggested the alternative patch due to the issues you raised in comment #2. I agree with you that extending the test to cover darwin would be by far the better solution. I'm unable to test your proposed patch, but it certainly looks reasonable, and I like it more that my patch. For what it's worth I think that would be a good change to make. Thanks.
[Bug fortran/99816] New: fortran do loop line table issue
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99816 Bug ID: 99816 Summary: fortran do loop line table issue Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: andrew.burgess at embecosm dot com Target Milestone: --- Consider this Fortran program: subroutine sub(a,n) dimension a(n) do 100 i = 1, n a(i) = i 100 continue ! Breakpoint here. return end subroutine sub program test dimension a(10) write(*,*) 'This is a test.' call sub(a,10) write(*,*) a end program test The line marked 'Breakpoint here' is line #5. I compile the test as: gfortran -g3 -O0 -o bug.x bug.f90 The run this GDB session: $ gdb bug.x (gdb) b 5 Breakpoint 1 at 0x4011de: file bug.f90, line 5. (gdb) r Starting program: /home/andrew/tmp/bug.x This is a test. Breakpoint 1, sub (a=..., n=10) at bug.f90:5 5 100 continue ! Breakpoint here. (gdb) c Continuing. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.000 [Inferior 1 (process 1170395) exited normally] Notice that the breakpoint was only hit once, despite line #5 being the last statement _within_ the loop. My expectation was that this breakpoint would be hit 10 times. I then look at the line table (I've truncated the output, but included the lines we care about): $ objdump --dwarf=decodedline bug.x bug.x: file format elf64-x86-64 Contents of the .debug_line section: CU: ./bug.f90: File nameLine numberStarting addressView Stmt bug.f9010x401176 x bug.f9010x401183 x bug.f9030x4011a7 x bug.f9030x4011b4 bug.f9040x4011c1 x bug.f9030x4011d8 x bug.f9050x4011de x bug.f9060x4011df x bug.f9070x4011e0 x bug.f9090x4011e3 x Finally, here's a snippet of the generated assembler code (from objdump -d) with an annotation of my own: 4011b4: 39 55 eccmp%edx,-0x14(%rbp) 4011b7: 0f 9f c0setg %al 4011ba: 0f b6 c0movzbl %al,%eax 4011bd: 85 c0 test %eax,%eax 4011bf: 75 1d jne4011de 4011c1: 8b 45 ecmov-0x14(%rbp),%eax 4011c4: 48 98 cltq 4011c6: 48 8d 48 ff lea-0x1(%rax),%rcx 4011ca: f3 0f 2a 45 ec cvtsi2ssl -0x14(%rbp),%xmm0 4011cf: 48 8b 45 d8 mov-0x28(%rbp),%rax 4011d3: f3 0f 11 04 88 movss %xmm0,(%rax,%rcx,4) 4011d8: 83 45 ec 01 addl $0x1,-0x14(%rbp) 4011dc: eb d6 jmp4011b4 4011de: 90 nop <--- Line 5 is recorded as here! 4011df: 90 nop 4011e0: 5b pop%rbx 4011e1: 5d pop%rbp 4011e2: c3 retq You can see that line 5 is clearly recorded at a point after the loop, hence why we only hit the breakpoint once. I've tested this with gfortran versions 'GNU Fortran (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)' (my distro's default version) and also with current HEAD of master branch (e19afa0645f).
[Bug fortran/99027] New: Incorrect ubound result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99027 Bug ID: 99027 Summary: Incorrect ubound result Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: andrew.burgess at embecosm dot com Target Milestone: --- I believe I have run into a case where ubound is giving the wrong result. Given: program test integer, dimension (1:3,1:6) :: array print *, "ubound = ", ubound (array (1, 1:4)) end program test I see the output: ubound =1 When I would have expected: ubound =4 Due to array (1, 1:4) being a 4 element 1-dimensional array. I am seeing this behaviour in my default Fedora compiler: GNU Fortran (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) But I also build current HEAD from git (26a3f288f18) and am still seeing this issue: GNU Fortran (GCC) 11.0.0 20210209 (experimental) Interestingly, if I change the test program to: program test integer, dimension (1:3,1:6) :: array print *, "ubound = ", ubound (array (1:2, 1:4)) end program test Then I do now see what I would expect for this case: ubound =2 4
[Bug fortran/99027] Incorrect ubound result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99027 Andrew Burgess changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #4 from Andrew Burgess --- Can confirm that with latest GCC HEAD I am now seeing the results that I expect. Thanks for the quick fix.