How the LLVM handle the debug location information of continue keyword and right brace(loop end location)?

If we had a very naïve way of generating IR, in the ‘continue’ case you would actually see TWO branch instructions: one to implement the ‘continue’ statement, and one as part of the control flow of the ‘for’ loop. The branch for the ‘continue’ statement would have the source location of the ‘continue’ and the branch for the control-flow of the ‘for’ loop would have the source location of the right brace.

Clang is smart enough that in the ‘continue’ example, it knows not to emit the second branch (it would be unreachable).

–paulr

This whole thread is confusing me.

Clang’s AST certainly knows where end braces are:

$ cat scope.cpp
int main() {
for (;:wink: {
}
}
$ clang++ scope.cpp -Xclang -ast-dump

-FunctionDecl 0xb914618 <scope.cpp:1:1, line:4:1> line:1:5 main 'int (void)' -CompoundStmt 0xb914768 <col:12, line:4:1>
`-ForStmt 0xb914730 <line:2:3, line:3:3>

-<<>>
-<<>>
-<<>>
-<<>>
`-CompoundStmt 0xb914718 <line:2:12, line:3:3>

But that seems orthogonal to both the question and the motivation for the question.

Both GCC and Clang use the ‘}’ of a function to place some instructions (at O0 at least) - so a function like:

1: int f(bool b) {
2: if (b)

3: return 3;
4: return 4;
5: }

Will step 1, 2, 3, 5 or 1, 2, 4, 5.

Loops could be done the same way, I suppose, but aren’t & I’m not really too fussed about that. If there’s some specific issue/problem/need here, happy to hear about/discuss it.

I did have a thread/review at some point, long ago, about some issues with the scope locations specifically related to exception cleanups, but it doesn’t seem to be relevant here.

All right, let us put away the LLVM IR, just look at issue C code:

The continue statement issue like this:

1int main()
2.{
3 int i;
4
5 for (i = 0; i < 256; i++) {
6 i++;
7 continue;
8 }
9}

When to use clang -g, we will not stop at continue stmt.

(gdb) b main
Breakpoint 1 at 0x100000f8b: file a.c, line 5.
(gdb) r

5 for (i = 0; i < 256; i++) {
(gdb) n
6 i++;
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) n
6 i++;
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) n
6 i++;
(gdb) n
There is no continue statement. However, we should stop at line 7 when we execute line 6.

But if we don’t have line 6

1int main()
2.{
3 int i;
4
5 for (i = 0; i < 256; i++) {
6 continue;
7 }
8}

(gdb) b main
Breakpoint 1 at 0x100000f8b: file a.c, line 5.
(gdb) r

5 for (i = 0; i < 256; i++) {
(gdb) n
6 continue;
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) b
6 continue;
(gdb) n
5 for (i = 0; i < 256; i++) {

We can stop at line 6 continue statement and don’t stop line 7 right brace.

The right brace statement issue like this:

1.int main()
2.{
3. int i;
4.
5. for (i = 0; i < 256; i++) {
6. }
7.}

When we use clang -g to compile it:

(gdb) b main
Breakpoint 1 at 0x100000f8b: file a.c, line 5.
(gdb) r
5 for (i = 0; i < 256; i++) {
(gdb) n
6 }
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) n
6 }
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) n
6 }

We will stop at line 6 right brace, but it should not stop.

If we add one statement:

1.int main()
2.{
3. int i;
4.
5. for (i = 0; i < 256; i++) {
6. i++;
7. }
8.}

(gdb) b main
Breakpoint 1 at 0x100000f7b: file a.c, line 5.
(gdb) r
5 for (i = 0; i < 256; i++) {
(gdb) n
6 i++;
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) n
6 i++;
(gdb) n
5 for (i = 0; i < 256; i++) {
(gdb) n
6 i++;

Everything is ok! we will not stop at line 7 right brace.