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

Passing variable with name stderr into closure causes c compilation error #22262

Closed
Tungsten-180 opened this issue Sep 20, 2024 · 2 comments · Fixed by #22263
Closed

Passing variable with name stderr into closure causes c compilation error #22262

Tungsten-180 opened this issue Sep 20, 2024 · 2 comments · Fixed by #22263
Assignees
Labels
Bug This tag is applied to issues which reports bugs. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: cgen Bugs/feature requests, that are related to the default C generating backend.

Comments

@Tungsten-180
Copy link

Tungsten-180 commented Sep 20, 2024

Describe the bug

Passing a variable with the names stdin,stdout, or stderr into a closure causes c compilation error.

Reproduction Steps

This should reproduce the bug:

fn other() {
	mut stderr:= 0
	causes_error := fn [mut stderr] (){
		stderr = 1
	}
	causes_error()
}

Expected Behavior

when causes_error is called it should do nothing but change the value of stderr to 1

Current Behavior

with v .

================== C compilation error (from tcc): ==============
cc: /tmp/v_1000/vlangbugreport.01J8729DJ5JMS8XZVEQVX6YZ5Q.tmp.c:2386: error: field not found: __v_stderr
=================================================================
(You can pass `-cg`, or `-show-c-output` as well, to print all the C error messages).
builder error:
==================
C error found. It should never happen, when compiling pure V code.
This is a V compiler bug, please report it using `v bug file.v`,
or goto https://github.com/vlang/v/issues/new/choose .
You can also use #help on Discord: https://discord.gg/vlang .

with -cg flag:

/tmp/v_1000/vlangbugreport.01J86RRKF3306VGEYC560WVM8V.tmp.c:3396: error: field not found: __v_stderr
builder error:

Possible Solution

Seems to be related to any variable with the name stdin, stdout, or stderr being passed into a closure.
Further investigation reveals that the closure's context struct is exported with the original variable name as field,
but then this generates a 'sanitized' name("__v_" + varname) to prevent reserved name colision. Somehow the var name
must be also be 'sanitized' when output elsewhere. (see Additional Info/Context)

Additional Information/Context

This is the generated c file(with another non error causing function; same code different variable names). There seems to be some issue with mangling the variable name into __v_stderr (to prevent a conflict?) but not doing that in the struct field.

struct _V_anon_fn_143c1662f75e5a6c__76_Ctx {
	int stderr;
};

VV_LOCAL_SYMBOL void anon_fn_143c1662f75e5a6c__76(void) {
	struct _V_anon_fn_143c1662f75e5a6c__76_Ctx* _V_closure_ctx = __CLOSURE_GET_DATA();
	_V_closure_ctx->__v_stderr = 0;
}


/*F*/
struct _V_anon_fn_143c1662f75e5a6c__182_Ctx {
	int no_conflict;
};

VV_LOCAL_SYMBOL void anon_fn_143c1662f75e5a6c__182(void) {
	struct _V_anon_fn_143c1662f75e5a6c__182_Ctx* _V_closure_ctx = __CLOSURE_GET_DATA();
	_V_closure_ctx->no_conflict = 0;
}

V version

V 0.4.7 9a0f4d8

Environment details (OS name and version, etc.)

tungsten@Federation:~/Documents/vlangbugreport$ v doctor
V full version: V 0.4.7 63957f2.9a0f4d8
OS: linux, Linux version 6.9.12-100.fc39.x86_64 (mockbuild@9543a464e37f4db8bd0fde43d10019f7) (gcc (GCC) 13.3.1 20240522 (Red Hat 13.3.1-1), GNU ld version 2.40-14.fc39) #1 SMP PREEMPT_DYNAMIC Sat Jul 27 16:09:11 UTC 2024
Processor: 16 cpus, 64bit, little endian, AMD Ryzen 7 5800X 8-Core Processor

getwd: /home/tungsten/Documents/vlangbugreport
vexe: /home/tungsten/v/v
vexe mtime: 2024-09-20 03:16:33

vroot: OK, value: /home/tungsten/v
VMODULES: OK, value: /home/tungsten/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.45.2
Git vroot status: weekly.2024.37-30-g9a0f4d84
.git/config present: true

CC version: cc (GCC) 13.3.1 20240522 (Red Hat 13.3.1-1)
thirdparty/tcc status: thirdparty-linux-amd64 0134e9b9

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.

@Tungsten-180 Tungsten-180 added the Bug This tag is applied to issues which reports bugs. label Sep 20, 2024
@Tungsten-180
Copy link
Author

this generates the symbol name:
vlib/v/gen/c/cgen.v line # 7227

fn c_name(name_ string) string {

and it doesn't match the var.name on
vlib/v/gen/c/fn.v line # 669

styp := g.typ(var.typ)
builder.writeln('\t${styp} ${var.name};')

because inherited var name is added here :
vlib/v/parser/fn.v line # 1206

var_name := p.prev_tok.lit

name is __v_stderr but struct field is stderr

struct _V_anon_fn_143c1662f75e5a6c__76_Ctx {
	int stderr;
};

VV_LOCAL_SYMBOL void anon_fn_143c1662f75e5a6c__76(void) {
	struct _V_anon_fn_143c1662f75e5a6c__76_Ctx* _V_closure_ctx = __CLOSURE_GET_DATA();
	_V_closure_ctx->__v_stderr = 0;
}

the above lines

int stderr;

and

    _V_closure_ctx->__v_stderr = 0;

are the problem
somehow the former needs to read

int __v_stderr;

@larpon
Copy link
Contributor

larpon commented Sep 20, 2024

Confirmed. Naming stderr to something else (e.g. stder) seems to fix the C error:

fn other() {
	mut stder:= 0
	causes_error := fn [mut stder] (){
		stder = 1
	}
	causes_error()
}

@larpon larpon added the Status: Confirmed This bug has been confirmed to be valid by a contributor. label Sep 20, 2024
@felipensp felipensp added the Unit: cgen Bugs/feature requests, that are related to the default C generating backend. label Sep 20, 2024
@felipensp felipensp self-assigned this Sep 20, 2024
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. Status: Confirmed This bug has been confirmed to be valid by a contributor. Unit: cgen Bugs/feature requests, that are related to the default C generating backend.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants