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

[Bug]: extern proc with varargs fails with non-literal param expression name #26759

Open
jabraham17 opened this issue Feb 21, 2025 · 4 comments

Comments

@jabraham17
Copy link
Member

Extern procs allow renaming, so they can be linked against one name in C and used by another name in Chapel. Extern procs also support varargs. These are a really convenient features for generic programming with C libraries, but I've found a case the compiler does not handle well

This program works fine, extern proc with varargs

extern proc printf(arg...);
printf("hello %f %f %f\n", 1.0, 2.0, 3.0);

This program also works fine, extern proc with a renaming with varargs

extern "printf" proc myprintf(arg...);
myprintf("hello %f %f %f\n", 1.0, 2.0, 3.0);

This program fails to resolve

param name = "printf";
extern name proc myprintf(arg...);
myprintf("hello %f %f %f\n", 1.0, 2.0, 3.0);
bug.chpl:3: error: unresolved call 'myprintf("hello %f %f %f\n", 1.0, 2.0, 3.0)'
bug.chpl:2: note: this candidate did not match: myprintf(arg ...)
bug.chpl:3: note: because actual argument #4 with type 'real(64)'
bug.chpl:2: note: is passed to formal '_chpl_cname: string'
@bradcray
Copy link
Member

It seems like a more accurate title would be to end with "non-literal param expression"? (From the title, I was expecting the second version not to work…). I also verified that a non-literal param works for a non-varargs cases, which seems notable as well:

param externName = "printf";
extern externName proc myprintf(arg);
myprintf("hello\n");

@jabraham17 jabraham17 changed the title [Bug]: extern proc with varargs fails with different name [Bug]: extern proc with varargs fails with non-literal param expression name Feb 24, 2025
@jabraham17
Copy link
Member Author

I've adjusted the title as suggested. I have a workaround I am using, as in my use case I know ahead of time how many args there will be, and so can constrain it

This program works fine

param n = 4;
param name = "printf";
extern name proc myprintf(arg...n);
myprintf("hello %f %f %f\n", 1.0, 2.0, 3.0);

I believe this bug arises from a quirk of the old compiler. Literal expressions for the name are resolved at AST build time when converting the dyno uAST to the production compilers AST. Non-literal expressions can't be resolved then (get resolved during actual resolution), so we insert a dummy trailing formal called _chpl_cname, and then remove that formal during function formal resolution. But that means we are trying to resolve proc foo(args..., _chpl_cname=string) and the current Chapel behavior is to greedily have _chpl_cname take the value of args.last, causing resolution to fail.

@bradcray
Copy link
Member

Does that suggest that once Dyno owns resolution, this should be resolved? And does it make you think we should wait for that to occur rather than trying to fix it on main?

@jabraham17
Copy link
Member Author

I strongly suspect that once dyno handles resolution this will just magically resolve. And because of that (and that for at least my specific case I have a workaround), I don't have a strong desire to try and fix it on main. I do think its a simple fix though, its just a matter changing how we thread the cname expr information to resolution to not abuse formal resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants