Thread overview
[Issue 5815] New: Using -O is causing wrong code to be generated for extern(C) method call.
Apr 06, 2011
Walter Bright
Apr 06, 2011
Rainer Schuetze
Apr 09, 2011
Rainer Schuetze
Apr 09, 2011
Rainer Schuetze
April 06, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815

           Summary: Using -O is causing wrong code to be generated for
                    extern(C) method call.
           Product: D
           Version: unspecified
          Platform: x86_64
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: opantm+spam@gmail.com


--- Comment #0 from opantm+spam@gmail.com 2011-04-06 10:55:30 PDT ---
When attempting to call a Windows API function, PathRemoveFileSpecA, invalid results are returned when using the -O compiler flag. When using the same file, but without -O, the correct output is generated.

Test Case:

import std.stdio;
import std.c.windows.windows;

static const ushort MAX_PATH = 260; extern(C) BOOL PathRemoveFileSpecA(LPTSTR);

static void TrimToNull(ref char[] String) {
    for(int i = 0; i < String.length; i++)
        if(String[i] == '\0') {
            String = String[0..i];
            return;
        }
}

static char[] GetDirectoryPath(string FilePath) {
    char[] Copy = FilePath.dup;
    uint Result = PathRemoveFileSpecA(Copy.ptr);
    TrimToNull(Copy);
    return Copy;
}

int main(string[] args) {
    string Path = "D:\\Test Path\\Test.exe";
    auto Dir = GetDirectoryPath(Path);
    writefln("Dir: " ~ Dir);
    return 0;
}


Output without -O: "Dir: D:\Test Path"
Output with -O: "object.Error: Access Violation"

For this particular example, shlwapi.lib must be generated with Implib.exe and linked.

The version of DMD being used is 2.052. OS is Windows, and compiled with: "dmd testfile.d shlwapi.lib (-O)".

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 06, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com
           Platform|x86_64                      |x86


--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> 2011-04-06 13:11:33 PDT ---
x86_64 (i.e. 64 bit code) is not currently supported by DMD on Windows.
Changing to x86.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 06, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815


Rainer Schuetze <r.sagitario@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |r.sagitario@gmx.de


--- Comment #2 from Rainer Schuetze <r.sagitario@gmx.de> 2011-04-06 14:09:38 PDT ---
> extern(C) BOOL PathRemoveFileSpecA(LPTSTR);

You are probably using the wrong calling convention here, it should be
"extern(Windows)", which corresponds to __stdcall in while "extern(C)" is
__cdecl in the SDK C++ headers.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 09, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815



--- Comment #3 from opantm+spam@gmail.com 2011-04-08 19:29:19 PDT ---
(In reply to comment #1)
> x86_64 (i.e. 64 bit code) is not currently supported by DMD on Windows.
> Changing to x86.

Sorry, I did mean x86.

(In reply to comment #2)
> > extern(C) BOOL PathRemoveFileSpecA(LPTSTR);
> 
> You are probably using the wrong calling convention here, it should be
> "extern(Windows)", which corresponds to __stdcall in while "extern(C)" is
> __cdecl in the SDK C++ headers.

As far as I can tell, the calling convention is C. According to MSDN, the
header is "BOOL PathRemoveFileSpec(__inout  LPTSTR pszPath)". As a comparison,
GetCurrentDirectory (which uses extern(Windows)) is "DWORD WINAPI
GetCurrentDirectory(__in   DWORD nBufferLength, __out  LPTSTR lpBuffer)". When
using extern(Windows), it fails to compile due to an undefined symbol error.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 09, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815



--- Comment #4 from Rainer Schuetze <r.sagitario@gmx.de> 2011-04-08 23:22:01 PDT ---
If you look it up in shlwapi.h in the SDK, it is declared as

LWSTDAPI_(BOOL)     PathRemoveFileSpecA(__inout LPSTR pszPath);

and LWSTDAPI_(BOOL) expands to 'extern "C" __declspec(dllimport) BOOL
__stdcall'.
__stdcall translates to D as extern(Windows).

I have tried your code, and I get a link error with "extern(C)". I have used coff2implib to convert the library from the sdk, because I have had problems with implib on DLLs in the past, it especially misses a number of symbols.

With "extern(Windows)", I can link and run your code without problems.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 09, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815



--- Comment #5 from Rainer Schuetze <r.sagitario@gmx.de> 2011-04-08 23:23:56 PDT ---
> I have used coff2implib

sorry, it is called coffimplib and available from the digitalmars ftp area.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 09, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5815


opantm+spam@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


--- Comment #6 from opantm+spam@gmail.com 2011-04-09 10:27:41 PDT ---
(In reply to comment #4)
> If you look it up in shlwapi.h in the SDK, it is declared as
> 
> LWSTDAPI_(BOOL)     PathRemoveFileSpecA(__inout LPSTR pszPath);
> 
> and LWSTDAPI_(BOOL) expands to 'extern "C" __declspec(dllimport) BOOL
> __stdcall'.
> __stdcall translates to D as extern(Windows).
> 
> I have tried your code, and I get a link error with "extern(C)". I have used coff2implib to convert the library from the sdk, because I have had problems with implib on DLLs in the past, it especially misses a number of symbols.
> 
> With "extern(Windows)", I can link and run your code without problems.

Awesome. After getting coffimplib and converting with it instead as well as changing to extern(Windows), it works both with and without -O. :) Thanks for the help. I guess this bug report is invalid.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------