Index: debuginfo-tests/trunk/win_cdb/inline-line-gap.cpp =================================================================== --- debuginfo-tests/trunk/win_cdb/inline-line-gap.cpp +++ debuginfo-tests/trunk/win_cdb/inline-line-gap.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cl -MD -Od %s -o %t.exe -fuse-ld=lld -Z7 +// RUN: grep DE[B]UGGER: %s | sed -e 's/.*DE[B]UGGER: //' > %t.script +// RUN: %cdb -cf %t.script %t.exe | FileCheck %s --check-prefixes=DEBUGGER,CHECK +// +// RUN: %clang_cl -MD -O2 %s -o %t.exe -fuse-ld=lld -Z7 +// RUN: grep DE[B]UGGER: %s | sed -e 's/.*DE[B]UGGER: //' > %t.script +// RUN: %cdb -cf %t.script %t.exe | FileCheck %s --check-prefixes=DEBUGGER,CHECK + +// This code is structured to have an early exit with an epilogue in the middle +// of the function, which creates a gap between the beginning of the inlined +// code region and the end. Previously, this confused cdb. + +volatile bool shutting_down_ = true; +volatile bool tearing_down_ = true; + +void __attribute__((optnone)) setCrashString(const char *) {} +void __attribute__((optnone)) doTailCall() {} +extern "C" void __declspec(noreturn) abort(); + +void __forceinline inlineCrashFrame() { + if (shutting_down_ || tearing_down_) { + setCrashString("crashing"); + __debugbreak(); + // MSVC lays out calls to abort out of line, gets the layout we want. + abort(); + } +} + +void __declspec(noinline) callerOfInlineCrashFrame(bool is_keeping_alive) { + if (is_keeping_alive) + inlineCrashFrame(); + else + doTailCall(); +} + +int __attribute__((optnone)) main() { + callerOfInlineCrashFrame(true); +} + +// DEBUGGER: g +// DEBUGGER: k3 +// CHECK: {{.*}}!inlineCrashFrame +// CHECK: {{.*}}!callerOfInlineCrashFrame +// CHECK: {{.*}}!main +// DEBUGGER: q