Skip to content

Missing is_stmt flag for 'else if' conditions #104695

@nd

Description

@nd

Originally from https://sourceware.org/bugzilla/show_bug.cgi?id=31896.

Sometimes if conditions don't get is_stmt flag and gdb skips them during stepping.

To reproduce, compile test.cpp:

 1  #include <iostream>
 2
 3  bool predicate(int v) {
 4      return v == 7;
 5  }
 6
 7  void f(int v) {
 8      if (v) { // break here
 9          std::cout << "branch1\n";
10      }
11      else if(predicate(v)) {
12          std::cout << "branch2\n";
13      } else if(predicate(v+1)) {
14          std::cout << "branch3\n";
15      }
16  }
17
18  int main() {
19      f(0);
20      return 0;
21  }

> clang++-18 -g -O0 test.cpp

Try stepping in gdb:

> gdb a.out
(gdb) b test.cpp:8
Breakpoint 1 at 0x116b: file test.cpp, line 8.
(gdb) run
Breakpoint 1, f (v=0) at test.cpp:8
8           if (v) { // break here
(gdb) next
11          else if(predicate(v)) {
(gdb) next
16      }
(gdb) 

Notice that gdb didn't stop at the last branch condition on line 13.

> llvm-dwarfdump-18 --debug-line a.out
...
Address            Line   Column File   ISA Discriminator OpIndex Flags
------------------ ------ ------ ------ --- ------------- ------- -------------
0x0000000000001140      3      0      0   0             0       0  is_stmt
0x0000000000001147      4     14      0   0             0       0  is_stmt prologue_end
0x000000000000114e      4      5      0   0             0       0 
0x0000000000001153      4      5      0   0             0       0  epilogue_begin
0x0000000000001160      7      0      0   0             0       0  is_stmt
0x000000000000116b      8      9      0   0             0       0  is_stmt prologue_end
0x000000000000116f      8      9      0   0             0       0 
0x0000000000001175      9     19      0   0             0       0  is_stmt
0x0000000000001188     10      5      0   0             0       0  is_stmt
0x000000000000118d     11     23      0   0             0       0  is_stmt
0x0000000000001190     11     13      0   0             0       0 
0x0000000000001195     11     13      0   0             0       0 
0x00000000000011a2     12     19      0   0             0       0  is_stmt
0x00000000000011b5     13      5      0   0             0       0  is_stmt
0x00000000000011ba     13     25      0   0             0       0 
0x00000000000011bd     13     26      0   0             0       0 
0x00000000000011c0     13     15      0   0             0       0 
0x00000000000011c5     13     15      0   0             0       0 
0x00000000000011d2     14     19      0   0             0       0  is_stmt
0x00000000000011e5      0     19      0   0             0       0 
0x00000000000011ef     16      1      0   0             0       0  is_stmt epilogue_begin
0x0000000000001200     18      0      0   0             0       0  is_stmt
0x000000000000120f     19      5      0   0             0       0  is_stmt prologue_end
0x0000000000001216     20      5      0   0             0       0  is_stmt
0x0000000000001218     20      5      0   0             0       0  epilogue_begin
0x000000000000121e     20      5      0   0             0       0  end_sequence

For the branch on the line 11 both closing } of the previous block on line 10 and the else if get is_stmt flag.

The branch on the line 13 has only one instruction marked with the is_stmt flag. Gdb treats it as the last instruction of the previous block and doesn't stop there.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions