Skip to content

Comments

Fix genCmain code to remove ambiguity of &main expression#2540

Merged
MartinNowak merged 2 commits intodlang:masterfrom
9rnsr:fix_main
Sep 9, 2013
Merged

Fix genCmain code to remove ambiguity of &main expression#2540
MartinNowak merged 2 commits intodlang:masterfrom
9rnsr:fix_main

Conversation

@9rnsr
Copy link
Contributor

@9rnsr 9rnsr commented Sep 9, 2013

It was introduced by pull #2476, but the expression &main which is implicitly
inserted would conflict with two extern(C) and (D) "main" functions in
user module.

Instead, separate the entry-point code in the hidden module __entrypoint.d

src/mars.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be obj_start(modules[0]->srcfile->toChars());.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will fix.

@MartinNowak
Copy link
Member

It was introduced by pull #2476, but the expression &main which is implicitly
inserted would conflict with two extern(C) and (D) "main" functions in
user module.

If there is a extern(C) main in the user module adding another extern(C) main makes two entry points.
This needs a little more thought, for example we could disallow extern(C) + extern(D) main. Any ideas?

@WalterBright
Copy link
Member

I don't understand the problem that this pull addresses?

@9rnsr
Copy link
Contributor Author

9rnsr commented Sep 9, 2013

By the #2476 change, extern(C) main is implicitly inserted in the place where extern(D) main exists.
After the insertion, the code would be made as follows.

// in user module
void main() { ... }  // user-defined extern(D) main

extern(C) {
int _d_run_main(int argc, char **argv, void* mainFunc);
int main(int argc, char **argv) { return _d_run_main(argc, argv, &main); }   // X
version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }
}

At the line X, the expression &main has essential ambiguity between the address of D main and C main. The problem will appear when #2130 is merged. (This is not just only an internal issue. D programmer can take the D main function address and test it like this. )

In other words, current entrypoint insertion way is relying on the current incorrect overload resolution behavior. After fixing the bug by #2130, it will cause a problem.

This PR fixes the currently hidden issue.

It was introduced by pull#2476, but the expression `&main` which is implicitly
inserted would conflict with two extern(C) and (D) "main" functions in
user module.

Instead, separate the entry-point code in the hidden module __entrypoint.d

Compiler will emit the generated C-main code in the same object file that
contains D-main code.
@9rnsr
Copy link
Contributor Author

9rnsr commented Sep 9, 2013

Updated to fix the bugs that pointed out by @dawgfoto.

Now, #2130 is based on this PR, and its auto-tester result also shows green (link).

src/mars.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crashes when you compile a library, because obj_write_deferred accesses Module::ident which is NULL.
This would work.

    Identifier *id = Lexer::idPool("__entrypoint");
    Module *m = new Module("__entrypoint.d", id, 0, 0);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much! Fixed.

MartinNowak added a commit that referenced this pull request Sep 9, 2013
Fix genCmain code to remove ambiguity of `&main` expression
@MartinNowak MartinNowak merged commit ce48a27 into dlang:master Sep 9, 2013
@9rnsr
Copy link
Contributor Author

9rnsr commented Sep 10, 2013

Thanks!

9rnsr added a commit to 9rnsr/dmd that referenced this pull request Oct 20, 2013
By dlang#2540 , implicitly defined C main has been moved to __entrypoint module. But, the codegen generates ModuleInfo symbol for the module. And vibe.d has its own main function in library. Then, compiling uer progam with vibe.d library will cause the conflict of two ModuleInfo symbols of __entrypoint module.

Due to avoid ModuleInfo symbol generation for __entrypoint, I added a special case in Module::genobjfile function. But, I'm not sure that the change won't cause any other problems...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants