Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable declarations after continue <label> cause builder error with -cc gcc -cstrict #19973

Open
ttytm opened this issue Nov 23, 2023 · 9 comments
Labels
Bug This tag is applied to issues which reports bugs. Unit: Checker Bugs/feature requests, that are related to the type checker.

Comments

@ttytm
Copy link
Member

ttytm commented Nov 23, 2023

Describe the bug

Compile the following with v -cc gcc -cstrict

Builder error:

outer: for i in 0 .. 10 {
	for j in 0 .. 10 {
		if i < 5 && j == 5 {
			println('j==5')
			continue outer
		}
	}
	var := 'abc'
	for k in 0 .. 10 {
		if k == 5 {
			println('k==5. use ${var}')
			continue outer
		}
	}
}

Workaround:

outer: for i in 0 .. 10 {
	mut continue_outer := false
	for j in 0 .. 10 {
		if i < 5 && j == 5 {
			println('j==5')
			continue_outer = true
			break
		}
	}
	if continue_outer {
		continue
	}
	var := 'abc'
	for k in 0 .. 10 {
		if k == 5 {
			println('k==5. use ${var}')
			continue outer
		}
	}
}

Reproduction Steps

above

Expected Behavior

works without workaround, as it does without -cstrict

Current Behavior

/tmp/v_1000/temp.17976900947943445950.tmp.c: In function ‘main__main’:
/tmp/v_1000/temp.17976900947943445950.tmp.c:12656:33: error: jump skips variable initialization [-Werror=jump-misses-init]
12656 |                                 goto outer__continue;
      |                                 ^~~~
/tmp/v_1000/temp.17976900947943445950.tmp.c:12660:17: note: label ‘outer__continue’ defined here
12660 |                 outer__continue: {}
      |                 ^~~~~~~~~~~~~~~
/tmp/v_1000/temp.17976900947943445950.tmp.c:12659:24: note: ‘var’ declared here
12659 |                 string var = _SLIT("abc");
      |                        ^~~
At top level:
cc1: note: unrecognized command-line option ‘-Wno-excess-initializers’ may have been intended to silence earlier diagnostics
...
==================
(Use `v -cg` to print the entire error message)

builder error: 

Possible Solution

No response

Additional Information/Context

No response

V version

v0.4.3

Environment details (OS name and version, etc.)

linux

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

@ttytm ttytm added the Bug This tag is applied to issues which reports bugs. label Nov 23, 2023
@felipensp
Copy link
Member

This is not a bug. You are skiping a variable declaration inside the outer loop.

What you can to do would it be:

outer: for i in 0 .. 10 {
	for j in 0 .. 10 {
		if i < 5 && j == 5 {
			println('j==5')
			continue
		}
	}
	var := 'abc'
	for k in 0 .. 10 {
		if k == 5 {
			println('k==5. use ${var}')
			continue outer
		}
	}
}

@ttytm
Copy link
Member Author

ttytm commented Nov 23, 2023

@felipensp yep, I know that the decl is skipped. I thought it should anyway translate into valid C. But deepening the thought, a fix seems very tough when labels use goto.

The suggestion is unfortunately not the same. It has way more load when not breaking the loop.

import time

sw := time.new_stopwatch()

outer: for i in 0 .. 1_000_000 {
	mut continue_outer := false
	for j in 0 .. 100 {
		if i < 500_000 && j == 5 {
			continue_outer = true
			break
		}
	}
	if continue_outer {
		continue
	}
	var := 'abc'
	for k in 0 .. 100 {
		if k == 5 {
			continue outer
		}
	}
}

dump(sw.elapsed())

Tcc run:

45ms
import time

sw := time.new_stopwatch()

outer: for i in 0 .. 1_000_000 {
	for j in 0 .. 100 {
		if i < 500_000 && j == 5 {
			continue
		}
	}
	var := 'abc'
	for k in 0 .. 100 {
		if k == 5 {
			continue outer
		}
	}
}

dump(sw.elapsed())
87ms

@felipensp
Copy link
Member

felipensp commented Nov 23, 2023

The C generated code is valid and represents what you have wrote. Who complains about is the GCC. Clang does not warns about it.

@ttytm
Copy link
Member Author

ttytm commented Nov 23, 2023

That's true. Then it's probably not a V bug and the issue can be closed.

@StunxFS
Copy link
Contributor

StunxFS commented Nov 23, 2023

What if the codegen generated the variable declarations at the beginning of the function?

void main__main(...) {
    string var;
    // ...
    var = STRLIT("abc");
    // ...
}

This way there shouldn't be any problem.

@felipensp
Copy link
Member

felipensp commented Nov 23, 2023

What if the codegen generated the variable declarations at the beginning of the function?

void main__main(...) {
    string var;
    // ...
    var = STRLIT("abc");
    // ...
}

This way there shouldn't be any problem.

In this case It seems better the user handle such cases (just as it would do coding in C) than add such automatic moving behavior for the V codegen.

@StunxFS
Copy link
Contributor

StunxFS commented Nov 23, 2023

What if the codegen generated the variable declarations at the beginning of the function?

void main__main(...) {
    string var;
    // ...
    var = STRLIT("abc");
    // ...
}

This way there shouldn't be any problem.

In this case It seems better the user handle such cases (just as it would do coding in C) than add such automatic moving behavior for the V codegen.

Clang does the same thing, that's why it doesn't show any error/warning about that, because when it generates LLVM, it declares the variables at the beginning and then initializes them in the proper place

@felipensp
Copy link
Member

Maybe the V checker could warn about such thing. What do you think @spytheman @medvednikov ?

@felipensp felipensp added the Unit: Checker Bugs/feature requests, that are related to the type checker. label Nov 23, 2023
@Delta456
Copy link
Member

Maybe the V checker could warn about such thing. What do you think @spytheman @medvednikov ?

Instead of a checker warn, I believe it should be vet warn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs. Unit: Checker Bugs/feature requests, that are related to the type checker.
Projects
None yet
Development

No branches or pull requests

4 participants