Hello list,

I'm currently adding D support to the MinGW targets. As the libphobos
upstream only targets newer msvcr runtime libraries, I tried building
GCC against libmsvcr120. When doing that, the build fails when building 
s-selftest-c++:

/home/jpfau/mingw-gcc-trunk/x86_64-trunk-win32-seh-rt_v6/build/gcc-trunk/./gcc/xgcc
 \
    
-B/home/jpfau/mingw-gcc-trunk/x86_64-trunk-win32-seh-rt_v6/build/gcc-trunk/./gcc/
 \
    -xc++ -nostdinc nul -S -o nul 
-fself-test=../../../../src/gcc-trunk/gcc/testsuite/selftests
xgcc.exe: error: nul: Invalid argument
xgcc.exe: warning: '-x c' after last input file has no effect
xgcc.exe: fatal error: no input files
compilation terminated.
make[2]: *** [../../../../src/gcc-trunk/gcc/cp/Make-lang.in:178: 
s-selftest-c++] Error 1

Debugging shows that the access function used to check
if the input files exist has different behavior in newer msvcr libraries:
It does return proper results for the 'nul' file in the old msvcrt.dll
but in newer libraries it returns EINVAL for the nul file.

I can think of at least two possible solutions:
1) Manually strcmp the input to find nul files. As far as I know there
   are many paths which count as nul files on windows, so it might be
   difficult to actually properly support all valid paths.
2) Use the windows API to check if the file exists.

A RFC patch for 2) is attached. I guess we don't want such platform
specific code in GCC, so any recommendation how to proceed? Should
this be placed in libiberty as a generic
int file_exists(const char *path, **error) instead?

Best regards,
Johannes

---
 gcc/gcc.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/gcc/gcc.c b/gcc/gcc.c
index 955a08cc8e8..674313facf1 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -45,6 +45,10 @@ compilation is specified by a string called a "spec".  */
 #include "filenames.h"
 #include "spellcheck.h"
 
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
 
 
 /* Manage the manipulation of env vars.
@@ -4552,12 +4556,26 @@ process_command (unsigned int decoded_options_count,
          else
            fname = xstrdup (arg);
 
-          if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
+#ifdef _WIN32
+         // _access does not work for the nul file on newer msvc versions
+         if (strcmp (fname, "-") != 0 && GetFileAttributes(fname) == 
INVALID_FILE_ATTRIBUTES)
+           {
+             bool resp = fname[0] == '@'
+                 && GetFileAttributes(fname + 1) == INVALID_FILE_ATTRIBUTES;
+
+             char error_msg[256] = "\0";
+             FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 
0,
+               (LPSTR)&error_msg, 256, NULL);
+             error ("%s: %s", fname + resp, error_msg);
+           }
+#else
+         if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
            {
              bool resp = fname[0] == '@' && access (fname + 1, F_OK) < 0;
              error ("%s: %m", fname + resp);
            }
-          else
+#endif
+         else
            add_infile (arg, spec_lang);
 
           free (fname);
-- 
2.19.2

Reply via email to