Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Debugger doesn't stop on "else if (<condition>)" #40614

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR41644
Status NEW
Importance P enhancement
Reported by Yuri (yuri@tsoft.com)
Reported on 2019-04-28 23:08:52 -0700
Last modified on 2019-05-03 07:45:33 -0700
Version 6.0
Hardware PC FreeBSD
CC aprantl@apple.com, blitzrakete@gmail.com, dblaikie@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, jeremy.morse.llvm@gmail.com, llvm-bugs@lists.llvm.org, paul_robinson@playstation.sony.com, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Testcase:

#include <iostream>

bool f1() {return false;}
bool f2() {return true;}

int main() {

  if (f1()) {
    std::cout << "1" << std::endl;
  } else if (f2()) {
    std::cout << "2" << std::endl;
  } else {
    std::cout << "3" << std::endl;
  }

  return 0;
}

Please build it (clang++ -g -o testcase testcase.cpp) and observe that right
after the f1() line the debugger steps on the "2" line, skipping f2().

gdb-8.2.1_3,
llvm80-8.0.0
FreeBSD 11.2 amd64
Quuxplusone commented 5 years ago
Looks like unfortunate interaction between how we pick source locations
and how we decide to set the "is_stmt" flag.

.LBB3_1:                                # %if.then
.Ltmp8:
    .loc    34 6 15 is_stmt 1       # t.cpp:6:15
    movabsq $_ZSt4cout, %rdi
    movabsq $.L.str, %rsi
    callq   _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
    .loc    34 6 22 is_stmt 0       # t.cpp:6:22
    movq    %rax, %rdi
    movabsq $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %rsi
    callq   _ZNSolsEPFRSoS_E
    movq    %rax, -16(%rbp)         # 8-byte Spill
    .loc    34 7 3 is_stmt 1        # t.cpp:7:3 <<<<< branch at end of block
    jmp .LBB3_6
.Ltmp9:
.LBB3_2:                                # %if.else
    .loc    34 7 14 is_stmt 0       # t.cpp:7:14 <<<<< if expr
    callq   _Z2f2v

The 'jmp .LBB3_6' is given the source location of the closing brace of the
block, which happens to be on the same line as the 'else if' expression,
which means our heuristic for setting 'is_stmt' fails.  gdb chooses to
respect the 'is_stmt' flag, and so doesn't stop at the evaluation of the
'else if' expression.

There are other circumstances where using the closing brace of the block
is the right thing to do, and there are other circumstances where the
difference in the column number doesn't indicate a "new statement," so
this isn't really simple to fix.  We'd have to track "statement" info
somehow through to final code emission, and use that to decide how to
set the is_stmt flag.  This is a known flaw in LLVM's debug info, and
this is one more example of it.