[LLVMbugs] [Bug 166] NEW: [llvmg++] Code generated to call through a pointer to member function is nasty
bugzilla-daemon at zion.cs.uiuc.edu
bugzilla-daemon at zion.cs.uiuc.edu
Sun Dec 7 22:59:26 PST 2003
http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=166
Summary: [llvmg++] Code generated to call through a pointer to
member function is nasty
Product: tools
Version: 1.0
Platform: All
OS/Version: All
Status: NEW
Severity: normal
Priority: P2
Component: llvm-g++
AssignedTo: sabre at nondot.org
ReportedBy: sabre at nondot.org
Consider a slightly simplified version of Brian's testcase for Bug 165:
----
struct Evil {
void fun ();
};
typedef void (Evil::*memfunptr) ();
memfunptr ptr = &Evil::fun;
void Evil::fun() {
(this->*ptr) ();
}
----
We currently generate the following LLVM code:
----
%struct.Evil = type { ubyte }
%ptr = global { void (%struct.Evil*)*, int } { void (%struct.Evil*)*
%_ZN4Evil3funEv, int 0 } ; <{ void (%struct.Evil*)*, int }*> [#uses=1]
implementation ; Functions:
void %_ZN4Evil3funEv(%struct.Evil* %this) {
entry:
%tmp.1 = load void (%struct.Evil*)** getelementptr ({ void
(%struct.Evil*)*, int }* %ptr, long 0, ubyte 0) ; <void
(%struct.Evil*)*> [#uses=2]
%tmp.2 = cast void (%struct.Evil*)* %tmp.1 to int ; <int>
[#uses=2]
%tmp.3 = and int %tmp.2, 1 ; <int> [#uses=1]
%tmp.4 = seteq int %tmp.3, 0 ; <bool> [#uses=1]
br bool %tmp.4, label %cond_true, label %cond_false
cond_true: ; preds = %entry
%tmp.351 = load int* getelementptr ({ void (%struct.Evil*)*, int }*
%ptr, long 0, ubyte 1) ; <int> [#uses=1]
%tmp.372 = cast int %tmp.351 to long ; <long> [#uses=1]
%tmp.363 = getelementptr %struct.Evil* %this, long %tmp.372
; <%struct.Evil*> [#uses=1]
call void %tmp.1( %struct.Evil* %tmp.363 )
ret void
cond_false: ; preds = %entry
%tmp.10 = load int* getelementptr ({ void (%struct.Evil*)*, int }* %ptr,
long 0, ubyte 1) ; <int> [#uses=1]
%tmp.12 = cast int %tmp.10 to long ; <long> [#uses=1]
%tmp.11 = getelementptr %struct.Evil* %this, long %tmp.12
; <%struct.Evil*> [#uses=2]
%tmp.13 = cast %struct.Evil* %tmp.11 to int (...)*** ; <int
(...)***> [#uses=1]
%tmp.14 = load int (...)*** %tmp.13 ; <int (...)**> [#uses=1]
%tmp.18 = cast int %tmp.2 to int (...)** ; <int (...)**>
[#uses=1]
%tmp.19 = cast int (...)** %tmp.14 to long ; <long> [#uses=1]
%tmp.20 = cast int (...)** %tmp.18 to long ; <long> [#uses=1]
%tmp.21 = add long %tmp.19, %tmp.20 ; <long> [#uses=1]
%tmp.22 = cast long %tmp.21 to int (...)** ; <int (...)**>
[#uses=1]
%tmp.26 = cast int (...)** %tmp.22 to long ; <long> [#uses=1]
%tmp.28 = add long %tmp.26, -1 ; <long> [#uses=1]
%tmp.29 = cast long %tmp.28 to void (%struct.Evil*)** ; <void
(%struct.Evil*)**> [#uses=1]
%tmp.31 = load void (%struct.Evil*)** %tmp.29 ; <void
(%struct.Evil*)*> [#uses=1]
call void %tmp.31( %struct.Evil* %tmp.11 )
ret void
}
----
This is gratuitously non-type-safe, and _might_ not actually even work if the
adjustment offset is non-zero (I'm not sure). This directly caused by the
non-LLVM C++ front-end code, so I'm not sure exactly how to fix it (I think
there is a target hook or something which controls this). In any case, masking
off the low bit of the function pointer seems like an extremely bad idea.
-Chris
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
More information about the llvm-bugs
mailing list