[PATCH] D11297: PR17829: Functions declared extern "C" with a name matching a mangled C++ function are allowed
Andrey Bokhanko via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 11 05:56:43 PDT 2015
andreybokhanko added a comment.
John,
(Others are welcome to chime in as well)
I started to implement your suggestion, but faced with problems.
Consider the following test case:
1: struct T {
2: ~T() {}
3: };
4:
5: extern "C" void _ZN1TD1Ev();
6:
7: int main() {
8: _ZN1TD1Ev();
9: T t;
10: }
First time we visit "GetOrCreateLLVMFunction" for "_ZN1TD1Ev" mangled name is when we are dealing with the call at line 8. No global values are associated with "_ZN1TD1Ev" name yet, so we simply create a new llvm::Function and add it to the list of module's functions (ParentModule->getFunctionList().push_back(this); at Function.cpp:264).
Next time we visit "GetOrCreateLLVMFunction" for the same "_ZN1TD1Ev" name is when we are dealing with the implicit t's destructor call at the end of "main" routine (say, at line 10). We already have a global value associated with "_ZN1TD1Ev" name *and* we have a function with this name in module's function list. We can't create a new llvm::Function and add it to the functions list -- since module's machinery asserts that there is only one function with a given mangled name in the list; we can't remove old Function either -- since it is referred to in the call at line 8. The best we can do is to bit cast old llvm::Function (from line 8) to destructor's type and return it. But this generates destructor call for a wrong llvm::Function which means problems and further asserts down the road.
Any hints how to resolve this?
Yours,
Andrey
P.S.: I honestly believe this code is incorrect (despite no definition for "ZN1TD1Ev" function), so in my opinion the way to go would be to issue a warning inside "GetOrCreateLLVMFunction". This is different from my initial patch and still compiles fine the following code -- which, as I believe, you meant as a correct use of explicitly mangled names:
struct T {
~T() {}
};
extern "C" void _ZN1TD1Ev(T *this_p);
int main() {
_ZN1TD1Ev(0);
T t;
}
(My initial patch warned even on this code, which is probably too strict indeed.)
http://reviews.llvm.org/D11297
More information about the cfe-commits
mailing list