Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] Win32 Clang patches #14889

Closed
p5pRT opened this issue Sep 4, 2015 · 12 comments
Closed

[PATCH] Win32 Clang patches #14889

p5pRT opened this issue Sep 4, 2015 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 4, 2015

Migrated from rt.perl.org#125982 (status was 'open')

Searchable as RT125982$

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2015

From @bulk88

Created by @bulk88

See attached patches. perl will not build with my clang-cl 3.5.0 with
these patches since I left out all the workarounds around clang bugs,
but these patches take care of most of the warnings that clang
shows+makefile support to actually use clang-cl.exe. Fixing the clang
warnings helps all the other non-clang compiler builds of perl, which is
half the point of these patches.

Perl Info

Flags:
          category=core
          severity=low

Site configuration information for perl 5.23.0:

Configured by Owner at Mon Jun 29 03:16:56 2015.

Summary of my perl5 (revision 5 version 23 subversion 0) configuration:
        Derived from: 63602a3fc27a417daf3c532b6a11ae6eba2a072a
        Platform:
          osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
          uname=''
          config_args='undef'
          hint=recommended, useposix=true, d_sigaction=undef
          useithreads=define, usemultiplicity=define
          use64bitint=undef, use64bitall=undef, uselongdouble=undef
          usemymalloc=n, bincompat5005=undef
        Compiler:
          cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG -GL 
-DWIN32
-D_CONSOLE -DNO_STRICT  -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -D_USE_32BIT_TIME_T',
          optimize='-O1 -MD -Zi -DNDEBUG -GL',
          cppflags='-DWIN32'
          ccversion='13.10.6030', gccversion='', gccosandvers=''
          intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234,
doublekind=3
          d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8,
longdblkind=0
          ivtype='long', ivsize=4, nvtype='double', nvsize=8,
Off_t='__int64', lseeksize=8
          alignbytes=8, prototype=define
        Linker and Libraries:
          ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf
-ltcg 		-libpath:"c:\perl\lib\CORE" 		-machine:x86'
          libpth=\lib
          libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
          perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
          libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl523.lib
          gnulibc_version=''
        Dynamic Linking:
          dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
          cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug
-opt:ref,icf -ltcg 		-libpath:"c:\perl\lib\CORE" 		-machine:x86'

Locally applied patches:
          uncommitted-changes


@INC for perl 5.23.0:
          C:/perl521/srcnewb4opt/lib
          .


Environment for perl 5.23.0:
          HOME (unset)
          LANG (unset)
          LANGUAGE (unset)
          LD_LIBRARY_PATH (unset)
          LOGDIR (unset)
          PATH=C:\sperl\c\bin;C:\WINDOWS\system32;C:\Program Files\Microsoft
Visual Studio .NET 2003\Vc7\bin;C:\Program Files\Microsoft Visual Studio
.NET 2003\Common7\IDE;C:\WINDOWS;C:\Program Files\Git\cmd;C:\Program
Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;C:\perl\bin
          PERL_BADLANG (unset)
          PERL_JSON_BACKEND=Cpanel::JSON::XS
          PERL_YAML_BACKEND=YAML
          SHELL (unset)









@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2015

From @bulk88

0001-Revert-makedef.pl-shouldn-t-prepend-Perl_-to-symbols.patch
From 971f079f502c66723d00529ea47882e9c1a798fa Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 21 Aug 2015 01:58:50 -0400
Subject: [PATCH 1/3] Revert "makedef.pl shouldn't prepend Perl_ to symbols
 already starting with Perl_."

This reverts commit cbe4d57f99858fe05f2e924ad9125b9b9e50504e.

Commit d1decf2be1 reverted the commit ahead of commit cbe4d57f99 for which
commit cbe4d57f99 was written. This makes cbe4d57f99 obsolete since
commit d1decf2be1 removed the "Perl_croak_memory_wrap" func from embed.fnc
and replaced it with a conservativly named "croak_memory_wrap". Reverting
commit cbe4d57f99 prepares the path for fixing the problem
that commit cbe4d57f99 tried to fix but failed (Perl_ prefix on exports
can't be prevented).
---
 makedef.pl |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/makedef.pl b/makedef.pl
index 1fee334..5f72291 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -690,8 +690,7 @@ unless ($define{'USE_QUADMATH'}) {
 	    # within the block, as the *first* definition may have flags which
 	    # mean "don't export"
 	    next if $seen{$func}++;
-	    # Should we also skip adding the Perl_ prefix if $flags =~ /o/ ?
-	    $func = "Perl_$func" if ($flags =~ /[pbX]/ && $func !~ /^Perl_/); 
+	    $func = "Perl_$func" if $flags =~ /[pbX]/;
 	    ++$export{$func} unless exists $skip{$func};
 	}
     }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2015

From @bulk88

0002-stop-makedef.pl-from-prefixing-Perl_-to-everything-u.patch
From e51b5234ba6cefb6ffda4574db1db5e5c5ad0089 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 21 Aug 2015 03:51:25 -0400
Subject: [PATCH 2/3] stop makedef.pl from prefixing "Perl_" to everything
 unconditionally

It was previously impossible to created an exported function that didn't
begin with Perl_. Turn off the A, you loose export, turn off the X, you
loose export, both A and X put the Perl_ prefix on. Commit cbe4d57f99
(now reverted) tried to fix the problem but failed, since the fix stoped
Perl_Perl_sv_setsomething but didn't stop Furl_sv_setsomething from
becoming Perl_Furl_sv_setsomething. Lots of the functions in /win32 are
called win32_*, not Perl_win32_*, since day 1 of /win32/win32.c
in 5.003_25. Currently these win32_* functions are declared with
"DllExport" macro in /win32/win32.h and special cased in makedef.pl, and
don't exist in embed.fnc. This is defective since win32.h is included so
early in perl.h that HASATTRIBUTE_NORETURN/HASATTRIBUTE_UNUSED aren't
defined yet and can't be used in win32.h declared C functions. This causes
clang-cl to warn about unused vars, and if HASATTRIBUTE_UNUSED or
Perl's  __attribute__unused__ macros/tokens are used to silence the unused
vars, those 2 aren't CPP converted to anything and breaks linking since
HASATTRIBUTE_UNUSED and Perl's __attribute__unused__ C symbols doesn't
exist, nor should they. By allowing the win32_* functions to go into
embed.fnc, they automatically and easily get CC specific flags in proto.h
specified for them, while doing it manually from win32.h would requiring
duplicating code from perl.h. Also less special casing in makedef.pl is
nice.

Removing X flagged functions from getting the Perl_ prefix doesn't change
perldll.def at all on threaded psuedofork Win32. There is one existing
win32_* func in embed.fnc
"norx	|void	|win32_croak_not_implemented|NN const char * fname"
in proto.h it is generated as

PERL_CALLCONV_NO_RET void	win32_croak_not_implemented(const char * fname)
			__attribute__noreturn__;

What is special about this is, that regen.pl didn't put a Perl_ prefix on
win32_croak_not_implemented, but if I change the x to X, proto.h stays as
win32_croak_not_implemented but perldll.def gets
a Perl_win32_croak_not_implemented symbol name, this shows that regen.pl
and proto.h are the correct behavior and makedef.pl is flawed. If you want
Perl_ prefix on non-public API but exported, you need "Xp" as the correct
flags, not "X" alone. Greping embed.fnc shows there are about 50 "Xp"
functions, so embed.fnc is also correct, and makedef.pl is flawed. There is
no precedent that says "X" alone means Perl_ prefix. So remove the X flag
from makedef.pl from triggering adding of the Perl_ prefix.

The origin of "X" flag triggering Perl_ prefix is commit db2b0bab8e from
5.9.0 commit db2b0bab8e changed Perl_ prefix by going from "p" alone to
"p", "b" and "X" when it implemented the "b" flag for the first time.
---
 makedef.pl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/makedef.pl b/makedef.pl
index 5f72291..8cfa323 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -690,7 +690,7 @@ unless ($define{'USE_QUADMATH'}) {
 	    # within the block, as the *first* definition may have flags which
 	    # mean "don't export"
 	    next if $seen{$func}++;
-	    $func = "Perl_$func" if $flags =~ /[pbX]/;
+	    $func = "Perl_$func" if $flags =~ /[pb]/;
 	    ++$export{$func} unless exists $skip{$func};
 	}
     }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2015

From @bulk88

0003-win32-clang-warnings-silence-beginnings-of-port.patch
From 977eafc147d417dee585e5fba461375025207762 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 4 Sep 2015 01:04:35 -0400
Subject: [PATCH 3/3] win32 clang warnings silence+beginnings of port

This patch does not fix all warnings, warnings likely to go away with newer
releases of Clang due to recent clang bug fixes, or warnings that are
probably inappropriate to Win32 (but are appropriate on Unix), or warnings
that should get tickets filed against Clang, are not fixed. clang-cl perl
blead does not build with this patch. Additional work+clang bug tickets are
required. In my private testing, only "lib/ExtUtils/t/Embed.t" had test
failures.

..\doio.c(2127,1) :  warning: unused function 'S_ingroup' [-Wunused-function]
S_ingroup(pTHX_ Gid_t testgid, bool effective)
^
Put S_ingroup in CPP conditional to silence the warning. Should make
building a tiny bit faster since the code isn't compile then tossed by
the CC or linker but removed very early at CPP phase.

In file included from perllib.c:10:
..\lib\CORE\perl.h(5845,62) :  warning: invalid suffix on literal; C++11
      requires a space between literal and identifier
      [-Wreserved-user-defined-literal]
                                        "Wide character (U+%"UVXf") in %s", \
                                                             ^
..\lib\CORE\perl.h(5855,42) :  warning: invalid suffix on literal; C++11
      requires a space between literal and identifier
      [-Wreserved-user-defined-literal]
                    "Wide character (U+%"UVXf") in %s",                     \
                                         ^
Add spaces to fix warning.

perllib.c(37,18) :  warning: ISO C++11 does not allow conversion from string
      literal to 'char *' [-Wwritable-strings]
    char *file = __FILE__;
                 ^
Add const to fix warning, do it in win32.c and wince.c too.

In file included from perllib.c:50:
./perlhost.h(2068,17) :  warning: using the result of an assignment as a
      condition without parentheses [-Wparentheses]
    while(lpPtr = host.GetIndex(dwIndex))
          ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
./perlhost.h(2068,17) :  note: place parentheses around the assignment to
      silence this warning
    while(lpPtr = host.GetIndex(dwIndex))
                ^
          (                             )
./perlhost.h(2068,17) :  note: use '==' to turn this assignment into an equality
      comparison
    while(lpPtr = host.GetIndex(dwIndex))
                ^
                ==
add parens to silence warning

..\pp_sys.c(2359,10) :  warning: unused variable 'targ' [-Wunused-variable]
    dSP; dTARGET;
         ^
../pp.h(82,22) :  note: expanded from macro 'dTARGET'
#define dTARGET SV * GETTARGET
                     ^
../pp.h(81,19) :  note: expanded from macro 'GETTARGET'
#define GETTARGET targ = PAD_SV(PL_op->op_targ)
                  ^
dTARGET in pp_ioctl is only used if the build config has fcntl/ioctl, and
Win32 miniperl doesn't have them. Move dTARGET close to first use to
silence the warning, and not store it as an auto around function calls.

..\pp_sys.c(5191,15) :  warning: unused variable 'stayopen' [-Wunused-variable]
    const int stayopen = TOPi;
              ^
Put stayopen in a CPP conditional to silence warning.

..\pp_sys.c(4865,1) :  warning: unused function 'S_space_join_names_mortal'
      [-Wunused-function]
S_space_join_names_mortal(pTHX_ char *const *array)
^
CPP remove it if socket-ish things aren't available, win32 miniperl doesnt
have sockets as an optimization

win32.c(140,14) :  warning: unused function 'wstr_to_str' [-Wunused-function]
static char*    wstr_to_str(const wchar_t* wstr);
                ^
Remove function with CPP conditionals to silence.

win32.c(2048,13) :  warning: format specifies type 'int' but the argument has
      type 'DWORD' (aka 'unsigned long') [-Wformat]
            g_osver.dwMajorVersion, g_osver.dwMinorVersion);
            ^~~~~~~~~~~~~~~~~~~~~~
win32.c(2048,37) :  warning: format specifies type 'int' but the argument has
      type 'DWORD' (aka 'unsigned long') [-Wformat]
            g_osver.dwMajorVersion, g_osver.dwMinorVersion);
                                    ^~~~~~~~~~~~~~~~~~~~~~
win32.c(2052,13) :  warning: format specifies type 'int' but the argument has
      type 'DWORD' (aka 'unsigned long') [-Wformat]
            g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT

change %d to %u, negative version numbers dont make sense, warning still
remains since the compiler still warns that "unsigned long" isnt
"unsigned int", but they are the same on Win32/Win64, so it is a possible
clang bug. This code will never run on unix so portability doesn't matter.

win32.c(2945,9) :  warning: unused variable 'lock_held' [-Wunused-variable]
    int lock_held = 0;

var lock_held was made obsolete in commit f06c882585
"[perl #77672] avoid a file handle redirection race", remove it entirely

win32.c(2604,16) :  warning: '_sys_nerr' redeclared without 'dllimport'
      attribute: previous 'dllimport' ignored
    extern int sys_nerr;
               ^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\stdlib.h(429,21)
:  note:
      expanded from macro 'sys_nerr'
#define sys_nerr    _sys_nerr
                    ^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\stdlib.h(194,20)
:  note:
      previous declaration is here
_CRTIMP extern int _sys_nerr;           /* # of entries in sys_errlist table */
                   ^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\stdlib.h(194,1) :
  note:
      previous attribute is here
_CRTIMP extern int _sys_nerr;           /* # of entries in sys_errlist table */
^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\tchar.h(47,28) :
 note:
      expanded from macro '_CRTIMP'
#define _CRTIMP __declspec(dllimport)
                           ^
        link -out:..\miniperl.exe @C:\WINDOWS\TEMP\nm6FA3.tmp
win32.obj : error LNK2001: unresolved external symbol __sys_nerr
..\miniperl.exe : fatal error LNK1120: 1 unresolved externals

This declaration of sys_nerr symbol, is as if it were undocumented in
the MS VC public CRT headers, but secretly exported, and therefore
requiring to declare it ourself makes no sense. VC6, the oldest supported
VC, declares sys_nerr in stdlib.h. VC apparantly doesn't care about this
definition, but clang with VC headers does. This declaration is from day 1
of win32.c in commit 0a753a7640. Remove it since it is obsolete and
causing clang build to fail.

..\util.c(1576,5) :  warning: function 'Perl_die_sv' declared 'noreturn' should
      not return [-Winvalid-noreturn]
    NORETURN_FUNCTION_END;
    ^
../perl.h(3488,46) :  note: expanded from macro 'NORETURN_FUNCTION_END'
#  define NORETURN_FUNCTION_END NOT_REACHED; return 0
                                             ^
..\util.c(1631,5) :  warning: function 'Perl_die' declared 'noreturn' should not

      return [-Winvalid-noreturn]
    NORETURN_FUNCTION_END;
    ^
../perl.h(3488,46) :  note: expanded from macro 'NORETURN_FUNCTION_END'
#  define NORETURN_FUNCTION_END NOT_REACHED; return 0
                                             ^
clang-cl does not have a __GNUC__/__GNUC_MINOR__ version number, it has a
_MSC_VER number instead, but it generates the same warnings as GCC, so
change perl.h so HASATTRIBUTE_NORETURN is turned on to silence that GCC
style warning, but this is a clang-cl build, so modify the build process so
that even though it is VC flavored clang, the GCC warnings and
"__attribute__()" macros will be turned on. The attributes must be turned
on, miniperl and full perl, so both builds are warning free. Problems
resulted that pTHX contains a "PERL_UNUSED_DECL" token from perl.h, but
win32.h is #included before some parts of perl.h have been loaded, so
win32.h is positioned too early to ever see the definition of
PERL_UNUSED_DECL. Move the 2 offending pTHX func declarations from
win32.h and put them in proto.h/embed.fnc where all other normal funtions
live, doing that solved the error where PERL_UNUSED_DECL was thought by
the CC to be a data symbol and the CC cant link it to undefined function
and clang fatally errored out. Turn on all the func attributes, not just
NORETURN and UNUSED, since it has to be done anyway for a clang win32
port of perl.

win32io.c(307,7) :  warning: unused variable 'code' [-Wunused-variable]
   IV code = 0;
      ^
var code has always been unused since it was added in commit 755e775944
therefore remove it

win32sck.c(343,12) :  warning: using the result of an assignment as a condition
      without parentheses [-Wparentheses]
    if(ret = WSAStartup(version, &retdata))

add parens to fix warning
---
 doio.c           |    2 +
 embed.fnc        |   14 ++++++++-
 embed.h          |   10 +++++-
 makedef.pl       |    1 -
 perl.h           |   10 ++++--
 pp_sys.c         |   24 ++++++++++++----
 proto.h          |   22 ++++++++++----
 win32/Makefile   |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 win32/perlhost.h |    2 +-
 win32/perllib.c  |    2 +-
 win32/win32.c    |   17 +++++------
 win32/win32.h    |    4 +--
 win32/win32io.c  |    1 -
 win32/win32sck.c |    2 +-
 win32/wince.c    |    2 +-
 15 files changed, 156 insertions(+), 39 deletions(-)

diff --git a/doio.c b/doio.c
index d038986..fdb319d 100644
--- a/doio.c
+++ b/doio.c
@@ -2123,6 +2123,7 @@ Perl_cando(pTHX_ Mode_t mode, bool effective, const Stat_t *statbufp)
 }
 #endif /* ! VMS */
 
+#ifndef DOSISH
 static bool
 S_ingroup(pTHX_ Gid_t testgid, bool effective)
 {
@@ -2156,6 +2157,7 @@ S_ingroup(pTHX_ Gid_t testgid, bool effective)
     return FALSE;
 #endif
 }
+#endif /* ! DOSISH */
 
 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
 
diff --git a/embed.fnc b/embed.fnc
index 1be276f..8633c80 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -369,6 +369,9 @@ Ap	|int	|do_aspawn	|NULLOK SV* really|NN SV** mark|NN SV** sp
 Ap	|int	|do_spawn	|NN char* cmd
 Ap	|int	|do_spawn_nowait|NN char* cmd
 #endif
+#if defined(WIN32) && defined(USE_ITHREADS)
+ox	|void	|win32_wait_for_children
+#endif
 #if !defined(WIN32)
 p	|bool	|do_exec3	|NN const char *incmd|int fd|int do_report
 #endif
@@ -632,7 +635,7 @@ AMp	|I32	|foldEQ_utf8_flags |NN const char *s1|NULLOK char **pe1|UV l1 \
 				|bool u1|NN const char *s2|NULLOK char **pe2 \
 				|UV l2|bool u2|U32 flags
 AnpP	|I32	|foldEQ_latin1	|NN const char* a|NN const char* b|I32 len
-#if defined(PERL_IN_DOIO_C)
+#if defined(PERL_IN_DOIO_C) && !defined(DOSISH)
 sR	|bool	|ingroup	|Gid_t testgid|bool effective
 #endif
 : Used in toke.c
@@ -1115,6 +1118,9 @@ ApdO	|I32	|call_method	|NN const char* methname|I32 flags
 ApdO	|I32	|call_pv	|NN const char* sub_name|I32 flags
 ApdO	|I32	|call_sv	|NN SV* sv|VOL I32 flags
 Ap	|void	|despatch_signals
+#if defined(WIN32)
+oX	|int	|win32_async_check
+#endif
 Ap	|OP *	|doref		|NN OP *o|I32 type|bool set_op_ref
 ApdO	|SV*	|eval_pv	|NN const char* p|I32 croak_on_error
 ApdO	|I32	|eval_sv	|NN SV* sv|I32 flags
@@ -2088,7 +2094,13 @@ s	|OP*	|doform		|NN CV *cv|NN GV *gv|NULLOK OP *retop
 #  if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
 sR	|int	|dooneliner	|NN const char *cmd|NN const char *filename
 #  endif
+#  if    defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)    \
+      || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)  \
+      || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)     \
+      || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)   \
+      || defined(HAS_GETSERVENT)
 s	|SV *	|space_join_names_mortal|NN char *const *array
+#  endif
 #endif
 p	|OP *	|tied_method|NN SV *methname|NN SV **sp \
 				|NN SV *const sv|NN const MAGIC *const mg \
diff --git a/embed.h b/embed.h
index faa4112..b775323 100644
--- a/embed.h
+++ b/embed.h
@@ -1411,6 +1411,11 @@
 #  if defined(DEBUG_LEAKING_SCALARS_FORK_DUMP)
 #define dump_sv_child(a)	Perl_dump_sv_child(aTHX_ a)
 #  endif
+#  if defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)          || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)        || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)           || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)         || defined(HAS_GETSERVENT)
+#    if defined(PERL_IN_PP_SYS_C)
+#define space_join_names_mortal(a)	S_space_join_names_mortal(aTHX_ a)
+#    endif
+#  endif
 #  if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
 #define do_ipcctl(a,b,c)	Perl_do_ipcctl(aTHX_ a,b,c)
 #define do_ipcget(a,b,c)	Perl_do_ipcget(aTHX_ a,b,c)
@@ -1457,10 +1462,12 @@
 #  endif
 #  if defined(PERL_IN_DOIO_C)
 #define exec_failed(a,b,c)	S_exec_failed(aTHX_ a,b,c)
-#define ingroup(a,b)		S_ingroup(aTHX_ a,b)
 #define openn_cleanup(a,b,c,d,e,f,g,h,i,j,k,l)	S_openn_cleanup(aTHX_ a,b,c,d,e,f,g,h,i,j,k,l)
 #define openn_setup(a,b,c,d,e,f)	S_openn_setup(aTHX_ a,b,c,d,e,f)
 #  endif
+#  if defined(PERL_IN_DOIO_C) && !defined(DOSISH)
+#define ingroup(a,b)		S_ingroup(aTHX_ a,b)
+#  endif
 #  if defined(PERL_IN_DOOP_C)
 #define do_trans_complex(a)	S_do_trans_complex(aTHX_ a)
 #define do_trans_complex_utf8(a)	S_do_trans_complex_utf8(aTHX_ a)
@@ -1662,7 +1669,6 @@
 #  endif
 #  if defined(PERL_IN_PP_SYS_C)
 #define doform(a,b,c)		S_doform(aTHX_ a,b,c)
-#define space_join_names_mortal(a)	S_space_join_names_mortal(aTHX_ a)
 #  endif
 #  if defined(PERL_IN_SCOPE_C)
 #define save_pushptri32ptr(a,b,c,d)	S_save_pushptri32ptr(aTHX_ a,b,c,d)
diff --git a/makedef.pl b/makedef.pl
index 8cfa323..6be59d2 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -756,7 +756,6 @@ if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) {
 			    Perl_win32_init
 			    Perl_win32_term
 			    RunPerl
-			    win32_async_check
 			    win32_errno
 			    win32_environ
 			    win32_abort
diff --git a/perl.h b/perl.h
index 7138e8a..2892662 100644
--- a/perl.h
+++ b/perl.h
@@ -5389,7 +5389,9 @@ struct tempsym; /* defined in pp_pack.c */
 
 /*
  * This provides a layer of functions and macros to ensure extensions will
- * get to use the same RTL functions as the core.
+ * get to use the same RTL functions as the core. This can also be used for
+ * for func declarations that require very late definition due to reliance on
+ * perl macros or types.
  */
 #if defined(WIN32)
 #  include "win32iop.h"
@@ -5840,8 +5842,8 @@ typedef struct am_table_short AMTS;
 	STMT_START {                                                        \
             if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) {         \
                 Perl_warner(aTHX_ packWARN(WARN_LOCALE),                    \
-                                        "Wide character (U+%"UVXf") in %s", \
-                                        (UV) cp, OP_DESC(PL_op));           \
+                                    "Wide character (U+%" UVXf ") in %s",   \
+                                    (UV) cp, OP_DESC(PL_op));               \
             }                                                               \
         }  STMT_END
 
@@ -5850,7 +5852,7 @@ typedef struct am_table_short AMTS;
             if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) {         \
                 UV cp = utf8_to_uvchr_buf((U8 *) s, (U8 *) send, NULL);     \
                 Perl_warner(aTHX_ packWARN(WARN_LOCALE),                    \
-                    "Wide character (U+%"UVXf") in %s",                     \
+                    "Wide character (U+%" UVXf ") in %s",                   \
                     (cp == 0)                                               \
                      ? UNICODE_REPLACEMENT                                  \
                      : (UV) cp,                                             \
diff --git a/pp_sys.c b/pp_sys.c
index 658dee1..e210a6e 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -2364,7 +2364,7 @@ PP(pp_truncate)
 
 PP(pp_ioctl)
 {
-    dSP; dTARGET;
+    dSP;
     SV * const argsv = POPs;
     const unsigned int func = POPu;
     int optype;
@@ -2427,11 +2427,14 @@ PP(pp_ioctl)
 
     if (retval == -1)
 	RETPUSHUNDEF;
-    if (retval != 0) {
-	PUSHi(retval);
-    }
-    else {
-	PUSHp(zero_but_true, ZBTLEN);
+    {
+	dTARGET;
+	if (retval != 0) {
+	    PUSHi(retval);
+	}
+	else {
+	    PUSHp(zero_but_true, ZBTLEN);
+	}
     }
 #endif
     RETURN;
@@ -4866,6 +4869,11 @@ PP(pp_semctl)
 #endif
 }
 
+#if    defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)    \
+    || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)  \
+    || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)     \
+    || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)   \
+    || defined(HAS_GETSERVENT)
 /* I can't const this further without getting warnings about the types of
    various arrays passed in from structures.  */
 static SV *
@@ -4888,6 +4896,7 @@ S_space_join_names_mortal(pTHX_ char *const *array)
     }
     return target;
 }
+#endif
 
 /* Get system info. */
 
@@ -5195,7 +5204,10 @@ PP(pp_gservent)
 PP(pp_shostent)
 {
     dSP;
+#if    defined(HAS_SETHOSTENT)  || defined(HAS_SETNETENT) \
+    || defined(HAS_SETPROTOENT) || defined(HAS_SETSERVENT)
     const int stayopen = TOPi;
+#endif
     switch(PL_op->op_type) {
     case OP_SHOSTENT:
 #ifdef HAS_SETHOSTENT
diff --git a/proto.h b/proto.h
index 1ddabd9..4d387c1 100644
--- a/proto.h
+++ b/proto.h
@@ -3834,6 +3834,13 @@ PERL_CALLCONV void	Perl_dump_sv_child(pTHX_ SV *sv);
 #define PERL_ARGS_ASSERT_DUMP_SV_CHILD	\
 	assert(sv)
 #endif
+#if defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)          || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)        || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)           || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)         || defined(HAS_GETSERVENT)
+#  if defined(PERL_IN_PP_SYS_C)
+STATIC SV *	S_space_join_names_mortal(pTHX_ char *const *array);
+#define PERL_ARGS_ASSERT_SPACE_JOIN_NAMES_MORTAL	\
+	assert(array)
+#  endif
+#endif
 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
 PERL_CALLCONV I32	Perl_do_ipcctl(pTHX_ I32 optype, SV** mark, SV** sp);
 #define PERL_ARGS_ASSERT_DO_IPCCTL	\
@@ -4067,9 +4074,6 @@ STATIC void	S_deb_stack_n(pTHX_ SV** stack_base, I32 stack_min, I32 stack_max, I
 STATIC void	S_exec_failed(pTHX_ const char *cmd, int fd, int do_report);
 #define PERL_ARGS_ASSERT_EXEC_FAILED	\
 	assert(cmd)
-STATIC bool	S_ingroup(pTHX_ Gid_t testgid, bool effective)
-			__attribute__warn_unused_result__;
-
 STATIC bool	S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, PerlIO *saveifp, PerlIO *saveofp, int savefd, char savetype, int writing, bool was_fdopen, const char *type);
 #define PERL_ARGS_ASSERT_OPENN_CLEANUP	\
 	assert(gv); assert(io); assert(mode); assert(oname)
@@ -4077,6 +4081,11 @@ STATIC IO *	S_openn_setup(pTHX_ GV *gv, char *mode, PerlIO **saveifp, PerlIO **s
 #define PERL_ARGS_ASSERT_OPENN_SETUP	\
 	assert(gv); assert(mode); assert(saveifp); assert(saveofp); assert(savefd); assert(savetype)
 #endif
+#if defined(PERL_IN_DOIO_C) && !defined(DOSISH)
+STATIC bool	S_ingroup(pTHX_ Gid_t testgid, bool effective)
+			__attribute__warn_unused_result__;
+
+#endif
 #if defined(PERL_IN_DOOP_C)
 STATIC I32	S_do_trans_complex(pTHX_ SV * const sv)
 			__attribute__warn_unused_result__;
@@ -4625,9 +4634,6 @@ STATIC I32	S_amagic_cmp_locale(pTHX_ SV *const str1, SV *const str2);
 STATIC OP*	S_doform(pTHX_ CV *cv, GV *gv, OP *retop);
 #define PERL_ARGS_ASSERT_DOFORM	\
 	assert(cv); assert(gv)
-STATIC SV *	S_space_join_names_mortal(pTHX_ char *const *array);
-#define PERL_ARGS_ASSERT_SPACE_JOIN_NAMES_MORTAL	\
-	assert(array)
 #endif
 #if defined(PERL_IN_REGCOMP_C)
 STATIC void	S__append_range_to_invlist(pTHX_ SV* const invlist, const UV start, const UV end);
@@ -5568,12 +5574,16 @@ PERL_CALLCONV const char*	Perl_quadmath_format_single(const char* format);
 PERL_CALLCONV char*	Perl_my_setlocale(pTHX_ int category, const char* locale)
 			__attribute__pure__;
 
+PERL_CALLCONV int	win32_async_check(pTHX);
 PERL_CALLCONV_NO_RET void	win32_croak_not_implemented(const char * fname)
 			__attribute__noreturn__;
 #define PERL_ARGS_ASSERT_WIN32_CROAK_NOT_IMPLEMENTED	\
 	assert(fname)
 
 #endif
+#if defined(WIN32) && defined(USE_ITHREADS)
+PERL_CALLCONV void	win32_wait_for_children(pTHX);
+#endif
 #if defined(WIN32) || defined(__SYMBIAN32__) || defined(VMS)
 PERL_CALLCONV int	Perl_do_aspawn(pTHX_ SV* really, SV** mark, SV** sp);
 #define PERL_ARGS_ASSERT_DO_ASPAWN	\
diff --git a/win32/Makefile b/win32/Makefile
index 2393e39..82b86be 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -3,6 +3,8 @@
 # Supported compilers:
 #	Microsoft Visual C++ 6.0 or later
 #	Windows SDK 64-bit compiler and tools
+#	Intel C Compiler (requires Visual C++ or Windows SDK)
+#
 #
 # This is set up to build a perl.exe that runs off a shared library
 # (perl523.dll).  Also makes individual DLLs for the XS extensions.
@@ -133,6 +135,11 @@ CCTYPE		= MSVC60
 #__ICC		= define
 
 #
+# If you are using the unsupported Clang Compiler uncomment this
+#
+#CLANG	= define
+
+#
 # Uncomment this if you want to build everything in C++ mode
 #
 #USE_CPLUSPLUS	= define
@@ -318,6 +325,12 @@ BUILDOPT	= $(BUILDOPT) -DPERL_IMPLICIT_SYS
 PROCESSOR_ARCHITECTURE	= x86
 !ENDIF
 
+!IF "$(CLANG)" != "" && "$(CLANG)" != "undef"
+__clang__= define
+!ELSE
+__clang__= undef
+!ENDIF
+
 !IF "$(WIN64)" == ""
 # When we are running from a 32bit cmd.exe on AMD64 then
 # PROCESSOR_ARCHITECTURE is set to x86 and PROCESSOR_ARCHITEW6432
@@ -338,6 +351,36 @@ WIN64			= undef
 USE_64_BIT_INT	= define
 !ENDIF
 
+!IF "$(__clang__)" == "define"
+#you csn't change VC headers/libs versions to build XS with clang-cl builds
+#like you can with plain VC
+!IF "$(CCTYPE)" == "MSVC60"
+EXTRACFLAGS	= -fmsc-version=1200
+!ELSE IF "$(CCTYPE)" == "MSVC70" || "$(CCTYPE)" == "MSVC70FREE"
+#this technically wrong since it doesn't separate msvcr70.dll CRT from
+#msvcr71.dll, but perl has no code that cares about 1300 vs 1310
+EXTRACFLAGS	= -fmsc-version=1300
+!ELSE IF "$(CCTYPE)" == "SDK2003SP1" || "$(CCTYPE)" == "MSVC80" || "$(CCTYPE)" == "MSVC80FREE"
+#SDK2003SP1 for Win64 I think uses msvcrt.dll which has known IOINFO struct size
+#but setting the version to 1400 causes the WIN32_DYN_IOINFO_SIZE code to be used
+#which is slightly less efficint since PSDK and VC2005 can't be separated by
+#CC version number
+EXTRACFLAGS	= -fmsc-version=1400
+!ELSE IF "$(CCTYPE)" == "MSVC90" || "$(CCTYPE)" == "MSVC90FREE"
+EXTRACFLAGS	= -fmsc-version=1500
+!ELSE IF "$(CCTYPE)" == "MSVC100" || "$(CCTYPE)" == "MSVC100FREE"
+EXTRACFLAGS	= -fmsc-version=1600
+!ELSE IF "$(CCTYPE)" == "MSVC110" || "$(CCTYPE)" == "MSVC110FREE"
+EXTRACFLAGS	= -fmsc-version=1700
+!ELSE IF "$(CCTYPE)" == "MSVC120" || "$(CCTYPE)" == "MSVC120FREE"
+EXTRACFLAGS	= -fmsc-version=1800
+!ELSE
+!ERROR unknown CCTYPE
+!ENDIF
+!ELSE
+EXTRACFLAGS	=
+!ENDIF
+
 # Treat 64-bit MSVC60 (doesn't really exist) as SDK2003SP1 because
 # both link against MSVCRT.dll (which is part of Windows itself) and
 # not against a compiler specific versioned runtime.
@@ -424,7 +467,11 @@ INST_HTML	= $(INST_TOP)$(INST_VER)\html
 #
 
 !IF "$(__ICC)" != "define"
+!IF "$(__clang__)" == "define"
+CC		= clang-cl
+!ELSE
 CC		= cl
+!ENDIF
 LINK32		= link
 !ELSE
 CC		= icl
@@ -527,8 +574,8 @@ LIBBASEFILES    = $(LIBBASEFILES) bufferoverflowU.lib
 
 LIBFILES	= $(LIBBASEFILES) $(LIBC)
 
-#EXTRACFLAGS	= -nologo -GF -W4 -wd4127 -wd4706
-EXTRACFLAGS	= -nologo -GF -W3
+#EXTRACFLAGS	= $(EXTRACFLAGS) -nologo -GF -W4 -wd4127 -wd4706
+EXTRACFLAGS	= $(EXTRACFLAGS) -nologo -GF -W3
 !IF "$(__ICC)" == "define"
 EXTRACFLAGS	= $(EXTRACFLAGS) -Qstd=c99
 !ENDIF
@@ -844,6 +891,16 @@ CFG_VARS	=					\
 		"ccflags=$(EXTRACFLAGS) $(OPTIMIZE:"=\") $(DEFINES) $(BUILDOPT)"	\
 		"usecplusplus=$(USE_CPLUSPLUS)"		\
 		"cf_email=$(EMAIL)"	 		\
+!IF "$(__clang__)" == "define"
+		"d_attribute_deprecated=define"		\
+		"d_attribute_format=define"		\
+		"d_attribute_malloc=define"		\
+		"d_attribute_nonnull=define"		\
+		"d_attribute_noreturn=define"		\
+		"d_attribute_pure=define"		\
+		"d_attribute_unused=define"		\
+		"d_attribute_warn_unused_result=define"	\
+!ENDIF
 		"d_mymalloc=$(PERL_MALLOC)"		\
 		"libs=$(LIBFILES)"			\
 		"incpath=$(CCINCDIR:"=\")"		\
@@ -932,6 +989,14 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #undef USE_64_BIT_INT>>$@
 	@echo #undef Size_t_size>>$@
 	@echo #undef USE_CPLUSPLUS>>$@
+	@echo #undef HASATTRIBUTE_DEPRECATED>>$@
+	@echo #undef HASATTRIBUTE_FORMAT>>$@
+	@echo #undef HASATTRIBUTE_MALLOC>>$@
+	@echo #undef HASATTRIBUTE_NONNULL>>$@
+	@echo #undef HASATTRIBUTE_NORETURN>>$@
+	@echo #undef HASATTRIBUTE_PURE>>$@
+	@echo #undef HASATTRIBUTE_UNUSED>>$@
+	@echo #undef HASATTRIBUTE_WARN_UNUSED_RESULT>>$@
 !IF "$(USE_LARGE_FILES)"=="define"
 	@echo #define Off_t __int64>>$@
 	@echo #define LSEEKSIZE ^8>>$@
@@ -983,6 +1048,19 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #define UVXf "lX">>$@
 	@echo #undef USE_64_BIT_INT>>$@
 !ENDIF
+!IF "$(__clang__)"=="define"
+#clang 1.0 docs say all of these are "ignored" or "supported"
+#ignored is as good as supported, no need know clang version and
+#avoid more conditionals based on clang version
+	@echo #define HASATTRIBUTE_DEPRECATED>>$@
+	@echo #define HASATTRIBUTE_FORMAT>>$@
+	@echo #define HASATTRIBUTE_MALLOC>>$@
+	@echo #define HASATTRIBUTE_NONNULL>>$@
+	@echo #define HASATTRIBUTE_NORETURN>>$@
+	@echo #define HASATTRIBUTE_PURE>>$@
+	@echo #define HASATTRIBUTE_UNUSED>>$@
+	@echo #define HASATTRIBUTE_WARN_UNUSED_RESULT>>$@
+!ENDIF
 !IF "$(USE_CPLUSPLUS)"=="define"
 	@echo #define USE_CPLUSPLUS>>$@
 !ELSE
diff --git a/win32/perlhost.h b/win32/perlhost.h
index 7a0c3b3..98492b3 100644
--- a/win32/perlhost.h
+++ b/win32/perlhost.h
@@ -2065,7 +2065,7 @@ CPerlHost::CPerlHost(CPerlHost& host)
     /* duplicate environment info */
     LPSTR lpPtr;
     DWORD dwIndex = 0;
-    while(lpPtr = host.GetIndex(dwIndex))
+    while((lpPtr = host.GetIndex(dwIndex)))
 	Add(lpPtr);
 }
 
diff --git a/win32/perllib.c b/win32/perllib.c
index 0e44a24..1d5005a 100644
--- a/win32/perllib.c
+++ b/win32/perllib.c
@@ -34,7 +34,7 @@ EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
 static void
 xs_init(pTHX)
 {
-    char *file = __FILE__;
+    const char *file = __FILE__;
     dXSUB_SYS;
     newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
     /* other similar records will be included from "perllibst.h" */
diff --git a/win32/win32.c b/win32/win32.c
index 2b883a2..0988cc3 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -137,7 +137,9 @@ static int	terminate_process(DWORD pid, HANDLE process_handle, int sig);
 static int	my_killpg(int pid, int sig);
 static int	my_kill(int pid, int sig);
 static void	out_of_memory(void);
+#ifdef _DEBUG
 static char*	wstr_to_str(const wchar_t* wstr);
+#endif
 static long	filetime_to_clock(PFILETIME ft);
 static BOOL	filetime_from_time(PFILETIME ft, time_t t);
 static char*	create_command_line(char *cname, STRLEN clen,
@@ -1670,6 +1672,7 @@ win32_croak_not_implemented(const char * fname)
 /* Converts a wide character (UTF-16) string to the Windows ANSI code page,
  * potentially using the system's default replacement character for any
  * unrepresentable characters. The caller must free() the returned string. */
+#ifdef _DEBUG
 static char*
 wstr_to_str(const wchar_t* wstr)
 {
@@ -1684,6 +1687,7 @@ wstr_to_str(const wchar_t* wstr)
                         str, len, NULL, &used_default);
     return str;
 }
+#endif
 
 /* The win32_ansipath() function takes a Unicode filename and converts it
  * into the current Windows codepage. If some characters cannot be mapped,
@@ -2044,11 +2048,11 @@ win32_uname(struct utsname *name)
     }
 
     /* release */
-    sprintf(name->release, "%d.%d",
+    sprintf(name->release, "%u.%u",
             g_osver.dwMajorVersion, g_osver.dwMinorVersion);
 
     /* version */
-    sprintf(name->version, "Build %d",
+    sprintf(name->version, "Build %u",
             g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT
             ? g_osver.dwBuildNumber : (g_osver.dwBuildNumber & 0xffff));
     if (g_osver.szCSDVersion[0]) {
@@ -2151,7 +2155,7 @@ sig_terminate(pTHX_ int sig)
     exit(sig);
 }
 
-DllExport int
+int
 win32_async_check(pTHX)
 {
     MSG msg;
@@ -2596,10 +2600,6 @@ extern int convert_errno_to_wsa_error(int err); /* in win32sck.c */
 DllExport char *
 win32_strerror(int e)
 {
-#if !defined __MINGW32__      /* compiler intolerance */
-    extern int sys_nerr;
-#endif
-
     if (e < 0 || e > sys_nerr) {
         dTHXa(NULL);
 	if (e < 0)
@@ -2942,7 +2942,6 @@ do_popen(const char *mode, const char *command, IV narg, SV **args) {
     int ourmode;
     int childpid;
     DWORD nhandle;
-    int lock_held = 0;
     const char **args_pvs = NULL;
 
     /* establish which ends read and write */
@@ -4213,7 +4212,7 @@ void
 Perl_init_os_extras(void)
 {
     dTHXa(NULL);
-    char *file = __FILE__;
+    const char *file = __FILE__;
 
     /* Initialize Win32CORE if it has been statically linked. */
 #ifndef PERL_IS_MINIPERL
diff --git a/win32/win32.h b/win32/win32.h
index 3b35b6c..001938d 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -263,7 +263,7 @@ PERL_STATIC_INLINE
 double S_Infinity() {
     /* this is a real C literal which can get further constant folded
        unlike using HUGE_VAL/_HUGE which are data symbol imports from the CRT
-       and therefore can not by folded by VC, an example of constant
+       and therefore can not be folded by VC, an example of constant
        folding INF is creating -INF */
     return (DBL_MAX+DBL_MAX);
 }
@@ -391,7 +391,6 @@ typedef struct {
 
 DllExport void		win32_get_child_IO(child_IO_table* ptr);
 DllExport HWND		win32_create_message_window(void);
-DllExport int		win32_async_check(pTHX);
 
 extern int		my_fclose(FILE *);
 extern char *		win32_get_privlib(const char *pl, STRLEN *const len);
@@ -529,7 +528,6 @@ struct interp_intern {
 #define w32_showwindow	(PL_sys_intern.thr_intern.Wshowwindow)
 
 #ifdef USE_ITHREADS
-void win32_wait_for_children(pTHX);
 #  define PERL_WAIT_FOR_CHILDREN win32_wait_for_children(aTHX)
 #endif
 
diff --git a/win32/win32io.c b/win32/win32io.c
index 00f5bb8..89a949d 100644
--- a/win32/win32io.c
+++ b/win32/win32io.c
@@ -304,7 +304,6 @@ PerlIOWin32_close(pTHX_ PerlIO *f)
  PerlIOWin32 *s = PerlIOSelf(f,PerlIOWin32);
  if (s->refcnt == 1)
   {
-   IV code = 0;	
 #if 0
    /* This does not do pipes etc. correctly */	
    if (!CloseHandle(s->h))
diff --git a/win32/win32sck.c b/win32/win32sck.c
index 3f97241..a2afdff 100644
--- a/win32/win32sck.c
+++ b/win32/win32sck.c
@@ -340,7 +340,7 @@ start_sockets(void)
      * cleaned up at exit.
      */
     version = 0x2;
-    if(ret = WSAStartup(version, &retdata))
+    if((ret = WSAStartup(version, &retdata)))
 	Perl_croak_nocontext("Unable to locate winsock library!\n");
     if(retdata.wVersion != version)
 	Perl_croak_nocontext("Could not find version 2.0 of winsock dll\n");
diff --git a/win32/wince.c b/win32/wince.c
index 1b58d40..e773aa2 100644
--- a/win32/wince.c
+++ b/win32/wince.c
@@ -2649,7 +2649,7 @@ void
 Perl_init_os_extras(void)
 {
     dTHX;
-    char *file = __FILE__;
+    const char *file = __FILE__;
     dXSUB_SYS;
 
     w32_perlshell_tokens = NULL;
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2015

From @bulk88

On Thu Sep 03 22​:43​:06 2015, bulk88 wrote​:

This is a bug report for perl from bulk88@​hotmail.com,
generated with the help of perlbug 1.40 running under perl 5.23.0.

-----------------------------------------------------------------
[Please describe your issue here]

See attached patches. perl will not build with my clang-cl 3.5.0 with
these patches since I left out all the workarounds around clang bugs,
but these patches take care of most of the warnings that clang
shows+makefile support to actually use clang-cl.exe. Fixing the clang
warnings helps all the other non-clang compiler builds of perl, which is
half the point of these patches.

rebased+clang-as-VC un-support added to makefile.mk, although Clang-as-GCC is missing from makefile.mk, some provisions exist for it in the makefile in the relationship between CCTYPE and CLANG macro.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2015

From @bulk88

On Wed Sep 09 13​:34​:58 2015, bulk88 wrote​:

On Thu Sep 03 22​:43​:06 2015, bulk88 wrote​:

This is a bug report for perl from bulk88@​hotmail.com,
generated with the help of perlbug 1.40 running under perl 5.23.0.

-----------------------------------------------------------------
[Please describe your issue here]

See attached patches. perl will not build with my clang-cl 3.5.0
with
these patches since I left out all the workarounds around clang bugs,
but these patches take care of most of the warnings that clang
shows+makefile support to actually use clang-cl.exe. Fixing the clang
warnings helps all the other non-clang compiler builds of perl, which
is
half the point of these patches.

rebased+clang-as-VC un-support added to makefile.mk, although Clang-
as-GCC is missing from makefile.mk, some provisions exist for it in
the makefile in the relationship between CCTYPE and CLANG macro.

No patches were posted, resending.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2015

From @bulk88

0001-Revert-makedef.pl-shouldn-t-prepend-Perl_-to-symbols.patch
From c77acee625674691a4d3fbeb243b1ba4ce44bbb9 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 21 Aug 2015 01:58:50 -0400
Subject: [PATCH 1/3] Revert "makedef.pl shouldn't prepend Perl_ to symbols
 already starting with Perl_."

This reverts commit cbe4d57f99858fe05f2e924ad9125b9b9e50504e.

Commit d1decf2be1 reverted the commit ahead of commit cbe4d57f99 for which
commit cbe4d57f99 was written. This makes cbe4d57f99 obsolete since
commit d1decf2be1 removed the "Perl_croak_memory_wrap" func from embed.fnc
and replaced it with a conservativly named "croak_memory_wrap". Reverting
commit cbe4d57f99 prepares the path for fixing the problem
that commit cbe4d57f99 tried to fix but failed (Perl_ prefix on exports
can't be prevented).
---
 makedef.pl |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/makedef.pl b/makedef.pl
index d1adad0..c45d3a3 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -691,8 +691,7 @@ unless ($define{'USE_QUADMATH'}) {
 	    # within the block, as the *first* definition may have flags which
 	    # mean "don't export"
 	    next if $seen{$func}++;
-	    # Should we also skip adding the Perl_ prefix if $flags =~ /o/ ?
-	    $func = "Perl_$func" if ($flags =~ /[pbX]/ && $func !~ /^Perl_/); 
+	    $func = "Perl_$func" if $flags =~ /[pbX]/;
 	    ++$export{$func} unless exists $skip{$func};
 	}
     }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2015

From @bulk88

0002-stop-makedef.pl-from-prefixing-Perl_-to-everything-u.patch
From dc1c66205d7fa49576180e5d1073c39c9b36ab66 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 21 Aug 2015 03:51:25 -0400
Subject: [PATCH 2/3] stop makedef.pl from prefixing "Perl_" to everything
 unconditionally

It was previously impossible to created an exported function that didn't
begin with Perl_. Turn off the A, you loose export, turn off the X, you
loose export, both A and X put the Perl_ prefix on. Commit cbe4d57f99
(now reverted) tried to fix the problem but failed, since the fix stoped
Perl_Perl_sv_setsomething but didn't stop Furl_sv_setsomething from
becoming Perl_Furl_sv_setsomething. Lots of the functions in /win32 are
called win32_*, not Perl_win32_*, since day 1 of /win32/win32.c
in 5.003_25. Currently these win32_* functions are declared with
"DllExport" macro in /win32/win32.h and special cased in makedef.pl, and
don't exist in embed.fnc. This is defective since win32.h is included so
early in perl.h that HASATTRIBUTE_NORETURN/HASATTRIBUTE_UNUSED aren't
defined yet and can't be used in win32.h declared C functions. This causes
clang-cl to warn about unused vars, and if HASATTRIBUTE_UNUSED or
Perl's  __attribute__unused__ macros/tokens are used to silence the unused
vars, those 2 aren't CPP converted to anything and breaks linking since
HASATTRIBUTE_UNUSED and Perl's __attribute__unused__ C symbols doesn't
exist, nor should they. By allowing the win32_* functions to go into
embed.fnc, they automatically and easily get CC specific flags in proto.h
specified for them, while doing it manually from win32.h would requiring
duplicating code from perl.h. Also less special casing in makedef.pl is
nice.

Removing X flagged functions from getting the Perl_ prefix doesn't change
perldll.def at all on threaded psuedofork Win32. There is one existing
win32_* func in embed.fnc
"norx	|void	|win32_croak_not_implemented|NN const char * fname"
in proto.h it is generated as

PERL_CALLCONV_NO_RET void	win32_croak_not_implemented(const char * fname)
			__attribute__noreturn__;

What is special about this is, that regen.pl didn't put a Perl_ prefix on
win32_croak_not_implemented, but if I change the x to X, proto.h stays as
win32_croak_not_implemented but perldll.def gets
a Perl_win32_croak_not_implemented symbol name, this shows that regen.pl
and proto.h are the correct behavior and makedef.pl is flawed. If you want
Perl_ prefix on non-public API but exported, you need "Xp" as the correct
flags, not "X" alone. Greping embed.fnc shows there are about 50 "Xp"
functions, so embed.fnc is also correct, and makedef.pl is flawed. There is
no precedent that says "X" alone means Perl_ prefix. So remove the X flag
from makedef.pl from triggering adding of the Perl_ prefix.

The origin of "X" flag triggering Perl_ prefix is commit db2b0bab8e from
5.9.0 commit db2b0bab8e changed Perl_ prefix by going from "p" alone to
"p", "b" and "X" when it implemented the "b" flag for the first time.
---
 makedef.pl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/makedef.pl b/makedef.pl
index c45d3a3..db47404 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -691,7 +691,7 @@ unless ($define{'USE_QUADMATH'}) {
 	    # within the block, as the *first* definition may have flags which
 	    # mean "don't export"
 	    next if $seen{$func}++;
-	    $func = "Perl_$func" if $flags =~ /[pbX]/;
+	    $func = "Perl_$func" if $flags =~ /[pb]/;
 	    ++$export{$func} unless exists $skip{$func};
 	}
     }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Sep 9, 2015

From @bulk88

0003-win32-clang-warnings-silence-beginnings-of-port.patch
From aa8ba9f68dec0f64ea185ca29b2f9bb325870d7c Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Wed, 9 Sep 2015 16:26:56 -0400
Subject: [PATCH 3/3] win32 clang warnings silence+beginnings of port

This patch does not fix all warnings, warnings likely to go away with newer
releases of Clang due to recent clang bug fixes, or warnings that are
probably inappropriate to Win32 (but are appropriate on Unix), or warnings
that should get tickets filed against Clang, are not fixed. clang-cl perl
blead does not build with this patch. Additional work+clang bug tickets are
required. In my private testing, only "lib/ExtUtils/t/Embed.t" had test
failures.

..\doio.c(2127,1) :  warning: unused function 'S_ingroup' [-Wunused-function]
S_ingroup(pTHX_ Gid_t testgid, bool effective)
^
Put S_ingroup in CPP conditional to silence the warning. Should make
building a tiny bit faster since the code isn't compile then tossed by
the CC or linker but removed very early at CPP phase.

In file included from perllib.c:10:
..\lib\CORE\perl.h(5845,62) :  warning: invalid suffix on literal; C++11
      requires a space between literal and identifier
      [-Wreserved-user-defined-literal]
                                        "Wide character (U+%"UVXf") in %s", \
                                                             ^
..\lib\CORE\perl.h(5855,42) :  warning: invalid suffix on literal; C++11
      requires a space between literal and identifier
      [-Wreserved-user-defined-literal]
                    "Wide character (U+%"UVXf") in %s",                     \
                                         ^
Add spaces to fix warning.

perllib.c(37,18) :  warning: ISO C++11 does not allow conversion from string
      literal to 'char *' [-Wwritable-strings]
    char *file = __FILE__;
                 ^
Add const to fix warning, do it in win32.c and wince.c too.

In file included from perllib.c:50:
./perlhost.h(2068,17) :  warning: using the result of an assignment as a
      condition without parentheses [-Wparentheses]
    while(lpPtr = host.GetIndex(dwIndex))
          ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
./perlhost.h(2068,17) :  note: place parentheses around the assignment to
      silence this warning
    while(lpPtr = host.GetIndex(dwIndex))
                ^
          (                             )
./perlhost.h(2068,17) :  note: use '==' to turn this assignment into an equality
      comparison
    while(lpPtr = host.GetIndex(dwIndex))
                ^
                ==
add parens to silence warning

..\pp_sys.c(2359,10) :  warning: unused variable 'targ' [-Wunused-variable]
    dSP; dTARGET;
         ^
../pp.h(82,22) :  note: expanded from macro 'dTARGET'
#define dTARGET SV * GETTARGET
                     ^
../pp.h(81,19) :  note: expanded from macro 'GETTARGET'
#define GETTARGET targ = PAD_SV(PL_op->op_targ)
                  ^
dTARGET in pp_ioctl is only used if the build config has fcntl/ioctl, and
Win32 miniperl doesn't have them. Move dTARGET close to first use to
silence the warning, and not store it as an auto around function calls.

..\pp_sys.c(5191,15) :  warning: unused variable 'stayopen' [-Wunused-variable]
    const int stayopen = TOPi;
              ^
Put stayopen in a CPP conditional to silence warning.

..\pp_sys.c(4865,1) :  warning: unused function 'S_space_join_names_mortal'
      [-Wunused-function]
S_space_join_names_mortal(pTHX_ char *const *array)
^
CPP remove it if socket-ish things aren't available, win32 miniperl doesnt
have sockets as an optimization

win32.c(140,14) :  warning: unused function 'wstr_to_str' [-Wunused-function]
static char*    wstr_to_str(const wchar_t* wstr);
                ^
Remove function with CPP conditionals to silence.

win32.c(2048,13) :  warning: format specifies type 'int' but the argument has
      type 'DWORD' (aka 'unsigned long') [-Wformat]
            g_osver.dwMajorVersion, g_osver.dwMinorVersion);
            ^~~~~~~~~~~~~~~~~~~~~~
win32.c(2048,37) :  warning: format specifies type 'int' but the argument has
      type 'DWORD' (aka 'unsigned long') [-Wformat]
            g_osver.dwMajorVersion, g_osver.dwMinorVersion);
                                    ^~~~~~~~~~~~~~~~~~~~~~
win32.c(2052,13) :  warning: format specifies type 'int' but the argument has
      type 'DWORD' (aka 'unsigned long') [-Wformat]
            g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT

change %d to %u, negative version numbers dont make sense, warning still
remains since the compiler still warns that "unsigned long" isnt
"unsigned int", but they are the same on Win32/Win64, so it is a possible
clang bug. This code will never run on unix so portability doesn't matter.

win32.c(2945,9) :  warning: unused variable 'lock_held' [-Wunused-variable]
    int lock_held = 0;

var lock_held was made obsolete in commit f06c882585
"[perl #77672] avoid a file handle redirection race", remove it entirely

win32.c(2604,16) :  warning: '_sys_nerr' redeclared without 'dllimport'
      attribute: previous 'dllimport' ignored
    extern int sys_nerr;
               ^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\stdlib.h(429,21)
:  note:
      expanded from macro 'sys_nerr'
#define sys_nerr    _sys_nerr
                    ^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\stdlib.h(194,20)
:  note:
      previous declaration is here
_CRTIMP extern int _sys_nerr;           /* # of entries in sys_errlist table */
                   ^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\stdlib.h(194,1) :
  note:
      previous attribute is here
_CRTIMP extern int _sys_nerr;           /* # of entries in sys_errlist table */
^
C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\INCLUDE\tchar.h(47,28) :
 note:
      expanded from macro '_CRTIMP'
#define _CRTIMP __declspec(dllimport)
                           ^
        link -out:..\miniperl.exe @C:\WINDOWS\TEMP\nm6FA3.tmp
win32.obj : error LNK2001: unresolved external symbol __sys_nerr
..\miniperl.exe : fatal error LNK1120: 1 unresolved externals

This declaration of sys_nerr symbol, is as if it were undocumented in
the MS VC public CRT headers, but secretly exported, and therefore
requiring to declare it ourself makes no sense. VC6, the oldest supported
VC, declares sys_nerr in stdlib.h. VC apparantly doesn't care about this
definition, but clang with VC headers does. This declaration is from day 1
of win32.c in commit 0a753a7640. Remove it since it is obsolete and
causing clang build to fail.

..\util.c(1576,5) :  warning: function 'Perl_die_sv' declared 'noreturn' should
      not return [-Winvalid-noreturn]
    NORETURN_FUNCTION_END;
    ^
../perl.h(3488,46) :  note: expanded from macro 'NORETURN_FUNCTION_END'
#  define NORETURN_FUNCTION_END NOT_REACHED; return 0
                                             ^
..\util.c(1631,5) :  warning: function 'Perl_die' declared 'noreturn' should not

      return [-Winvalid-noreturn]
    NORETURN_FUNCTION_END;
    ^
../perl.h(3488,46) :  note: expanded from macro 'NORETURN_FUNCTION_END'
#  define NORETURN_FUNCTION_END NOT_REACHED; return 0
                                             ^
clang-cl does not have a __GNUC__/__GNUC_MINOR__ version number, it has a
_MSC_VER number instead, but it generates the same warnings as GCC, so
change perl.h so HASATTRIBUTE_NORETURN is turned on to silence that GCC
style warning, but this is a clang-cl build, so modify the build process so
that even though it is VC flavored clang, the GCC warnings and
"__attribute__()" macros will be turned on. The attributes must be turned
on, miniperl and full perl, so both builds are warning free. Problems
resulted that pTHX contains a "PERL_UNUSED_DECL" token from perl.h, but
win32.h is #included before some parts of perl.h have been loaded, so
win32.h is positioned too early to ever see the definition of
PERL_UNUSED_DECL. Move the 2 offending pTHX func declarations from
win32.h and put them in proto.h/embed.fnc where all other normal funtions
live, doing that solved the error where PERL_UNUSED_DECL was thought by
the CC to be a data symbol and the CC cant link it to undefined function
and clang fatally errored out. Turn on all the func attributes, not just
NORETURN and UNUSED, since it has to be done anyway for a clang win32
port of perl.

win32io.c(307,7) :  warning: unused variable 'code' [-Wunused-variable]
   IV code = 0;
      ^
var code has always been unused since it was added in commit 755e775944
therefore remove it

win32sck.c(343,12) :  warning: using the result of an assignment as a condition
      without parentheses [-Wparentheses]
    if(ret = WSAStartup(version, &retdata))

add parens to fix warning
---
 doio.c            |    2 +
 embed.fnc         |   14 ++++++++-
 embed.h           |   10 +++++-
 makedef.pl        |    1 -
 perl.h            |   10 +++--
 pp_sys.c          |   24 ++++++++++---
 proto.h           |   22 +++++++++---
 win32/Makefile    |   82 +++++++++++++++++++++++++++++++++++++++++++++++-
 win32/makefile.mk |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 win32/perlhost.h  |    2 +-
 win32/perllib.c   |    2 +-
 win32/win32.c     |   17 +++++-----
 win32/win32.h     |    4 +--
 win32/win32io.c   |    1 -
 win32/win32sck.c  |    2 +-
 win32/wince.c     |    2 +-
 16 files changed, 243 insertions(+), 42 deletions(-)

diff --git a/doio.c b/doio.c
index b2d269b..1791b38 100644
--- a/doio.c
+++ b/doio.c
@@ -2174,6 +2174,7 @@ Perl_cando(pTHX_ Mode_t mode, bool effective, const Stat_t *statbufp)
 }
 #endif /* ! VMS */
 
+#ifndef DOSISH
 static bool
 S_ingroup(pTHX_ Gid_t testgid, bool effective)
 {
@@ -2207,6 +2208,7 @@ S_ingroup(pTHX_ Gid_t testgid, bool effective)
     return FALSE;
 #endif
 }
+#endif /* ! DOSISH */
 
 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
 
diff --git a/embed.fnc b/embed.fnc
index f1abcd0..7e55200 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -370,6 +370,9 @@ Ap	|int	|do_aspawn	|NULLOK SV* really|NN SV** mark|NN SV** sp
 Ap	|int	|do_spawn	|NN char* cmd
 Ap	|int	|do_spawn_nowait|NN char* cmd
 #endif
+#if defined(WIN32) && defined(USE_ITHREADS)
+ox	|void	|win32_wait_for_children
+#endif
 #if !defined(WIN32)
 p	|DO_EXEC_TYPE|do_exec3	|NN const char *incmd|int fd|int do_report
 #endif
@@ -633,7 +636,7 @@ AMp	|I32	|foldEQ_utf8_flags |NN const char *s1|NULLOK char **pe1|UV l1 \
 				|bool u1|NN const char *s2|NULLOK char **pe2 \
 				|UV l2|bool u2|U32 flags
 AnpP	|I32	|foldEQ_latin1	|NN const char* a|NN const char* b|I32 len
-#if defined(PERL_IN_DOIO_C)
+#if defined(PERL_IN_DOIO_C) && !defined(DOSISH)
 sR	|bool	|ingroup	|Gid_t testgid|bool effective
 #endif
 : Used in toke.c
@@ -1116,6 +1119,9 @@ ApdO	|I32	|call_method	|NN const char* methname|I32 flags
 ApdO	|I32	|call_pv	|NN const char* sub_name|I32 flags
 ApdO	|I32	|call_sv	|NN SV* sv|VOL I32 flags
 Ap	|void	|despatch_signals
+#if defined(WIN32)
+oX	|int	|win32_async_check
+#endif
 Ap	|OP *	|doref		|NN OP *o|I32 type|bool set_op_ref
 ApdO	|SV*	|eval_pv	|NN const char* p|I32 croak_on_error
 ApdO	|I32	|eval_sv	|NN SV* sv|I32 flags
@@ -2089,7 +2095,13 @@ s	|OP*	|doform		|NN CV *cv|NN GV *gv|NULLOK OP *retop
 #  if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
 sR	|int	|dooneliner	|NN const char *cmd|NN const char *filename
 #  endif
+#  if    defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)    \
+      || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)  \
+      || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)     \
+      || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)   \
+      || defined(HAS_GETSERVENT)
 s	|SV *	|space_join_names_mortal|NN char *const *array
+#  endif
 #endif
 p	|OP *	|tied_method|NN SV *methname|NN SV **sp \
 				|NN SV *const sv|NN const MAGIC *const mg \
diff --git a/embed.h b/embed.h
index 3f6515f..c7b768a 100644
--- a/embed.h
+++ b/embed.h
@@ -1414,6 +1414,11 @@
 #  if defined(DEBUG_LEAKING_SCALARS_FORK_DUMP)
 #define dump_sv_child(a)	Perl_dump_sv_child(aTHX_ a)
 #  endif
+#  if defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)          || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)        || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)           || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)         || defined(HAS_GETSERVENT)
+#    if defined(PERL_IN_PP_SYS_C)
+#define space_join_names_mortal(a)	S_space_join_names_mortal(aTHX_ a)
+#    endif
+#  endif
 #  if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
 #define do_ipcctl(a,b,c)	Perl_do_ipcctl(aTHX_ a,b,c)
 #define do_ipcget(a,b,c)	Perl_do_ipcget(aTHX_ a,b,c)
@@ -1460,10 +1465,12 @@
 #  endif
 #  if defined(PERL_IN_DOIO_C)
 #define exec_failed(a,b,c)	S_exec_failed(aTHX_ a,b,c)
-#define ingroup(a,b)		S_ingroup(aTHX_ a,b)
 #define openn_cleanup(a,b,c,d,e,f,g,h,i,j,k,l)	S_openn_cleanup(aTHX_ a,b,c,d,e,f,g,h,i,j,k,l)
 #define openn_setup(a,b,c,d,e,f)	S_openn_setup(aTHX_ a,b,c,d,e,f)
 #  endif
+#  if defined(PERL_IN_DOIO_C) && !defined(DOSISH)
+#define ingroup(a,b)		S_ingroup(aTHX_ a,b)
+#  endif
 #  if defined(PERL_IN_DOOP_C)
 #define do_trans_complex(a)	S_do_trans_complex(aTHX_ a)
 #define do_trans_complex_utf8(a)	S_do_trans_complex_utf8(aTHX_ a)
@@ -1665,7 +1672,6 @@
 #  endif
 #  if defined(PERL_IN_PP_SYS_C)
 #define doform(a,b,c)		S_doform(aTHX_ a,b,c)
-#define space_join_names_mortal(a)	S_space_join_names_mortal(aTHX_ a)
 #  endif
 #  if defined(PERL_IN_SCOPE_C)
 #define save_pushptri32ptr(a,b,c,d)	S_save_pushptri32ptr(aTHX_ a,b,c,d)
diff --git a/makedef.pl b/makedef.pl
index db47404..653f3a5 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -757,7 +757,6 @@ if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) {
 			    Perl_win32_init
 			    Perl_win32_term
 			    RunPerl
-			    win32_async_check
 			    win32_errno
 			    win32_environ
 			    win32_abort
diff --git a/perl.h b/perl.h
index cb877a3..998596b 100644
--- a/perl.h
+++ b/perl.h
@@ -5412,7 +5412,9 @@ struct tempsym; /* defined in pp_pack.c */
 
 /*
  * This provides a layer of functions and macros to ensure extensions will
- * get to use the same RTL functions as the core.
+ * get to use the same RTL functions as the core. This can also be used for
+ * for func declarations that require very late definition due to reliance on
+ * perl macros or types.
  */
 #if defined(WIN32)
 #  include "win32iop.h"
@@ -5878,8 +5880,8 @@ typedef struct am_table_short AMTS;
 	STMT_START {                                                        \
             if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) {         \
                 Perl_warner(aTHX_ packWARN(WARN_LOCALE),                    \
-                                        "Wide character (U+%"UVXf") in %s", \
-                                        (UV) cp, OP_DESC(PL_op));           \
+                                    "Wide character (U+%" UVXf ") in %s",   \
+                                    (UV) cp, OP_DESC(PL_op));               \
             }                                                               \
         }  STMT_END
 
@@ -5888,7 +5890,7 @@ typedef struct am_table_short AMTS;
             if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) {         \
                 UV cp = utf8_to_uvchr_buf((U8 *) s, (U8 *) send, NULL);     \
                 Perl_warner(aTHX_ packWARN(WARN_LOCALE),                    \
-                    "Wide character (U+%"UVXf") in %s",                     \
+                    "Wide character (U+%" UVXf ") in %s",                   \
                     (cp == 0)                                               \
                      ? UNICODE_REPLACEMENT                                  \
                      : (UV) cp,                                             \
diff --git a/pp_sys.c b/pp_sys.c
index c8c84b3..cc7595c 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -2368,7 +2368,7 @@ PP(pp_truncate)
 
 PP(pp_ioctl)
 {
-    dSP; dTARGET;
+    dSP;
     SV * const argsv = POPs;
     const unsigned int func = POPu;
     int optype;
@@ -2431,11 +2431,14 @@ PP(pp_ioctl)
 
     if (retval == -1)
 	RETPUSHUNDEF;
-    if (retval != 0) {
-	PUSHi(retval);
-    }
-    else {
-	PUSHp(zero_but_true, ZBTLEN);
+    {
+	dTARGET;
+	if (retval != 0) {
+	    PUSHi(retval);
+	}
+	else {
+	    PUSHp(zero_but_true, ZBTLEN);
+	}
     }
 #endif
     RETURN;
@@ -4929,6 +4932,11 @@ PP(pp_semctl)
 #endif
 }
 
+#if    defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)    \
+    || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)  \
+    || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)     \
+    || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)   \
+    || defined(HAS_GETSERVENT)
 /* I can't const this further without getting warnings about the types of
    various arrays passed in from structures.  */
 static SV *
@@ -4951,6 +4959,7 @@ S_space_join_names_mortal(pTHX_ char *const *array)
     }
     return target;
 }
+#endif
 
 /* Get system info. */
 
@@ -5258,7 +5267,10 @@ PP(pp_gservent)
 PP(pp_shostent)
 {
     dSP;
+#if    defined(HAS_SETHOSTENT)  || defined(HAS_SETNETENT) \
+    || defined(HAS_SETPROTOENT) || defined(HAS_SETSERVENT)
     const int stayopen = TOPi;
+#endif
     switch(PL_op->op_type) {
     case OP_SHOSTENT:
 #ifdef HAS_SETHOSTENT
diff --git a/proto.h b/proto.h
index 4d3465f..f8b99db 100644
--- a/proto.h
+++ b/proto.h
@@ -3840,6 +3840,13 @@ PERL_CALLCONV void	Perl_dump_sv_child(pTHX_ SV *sv);
 #define PERL_ARGS_ASSERT_DUMP_SV_CHILD	\
 	assert(sv)
 #endif
+#if defined(HAS_GETNETBYNAME)        || defined(HAS_GETNETBYADDR)          || defined(HAS_GETNETENT)           || defined(HAS_GETPROTOBYNAME)        || defined(HAS_GETPROTOBYNUMBER)    || defined(HAS_GETPROTOENT)           || defined(HAS_GETSERVBYNAME)       || defined(HAS_GETSERVBYPORT)         || defined(HAS_GETSERVENT)
+#  if defined(PERL_IN_PP_SYS_C)
+STATIC SV *	S_space_join_names_mortal(pTHX_ char *const *array);
+#define PERL_ARGS_ASSERT_SPACE_JOIN_NAMES_MORTAL	\
+	assert(array)
+#  endif
+#endif
 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
 PERL_CALLCONV I32	Perl_do_ipcctl(pTHX_ I32 optype, SV** mark, SV** sp);
 #define PERL_ARGS_ASSERT_DO_IPCCTL	\
@@ -4073,9 +4080,6 @@ STATIC void	S_deb_stack_n(pTHX_ SV** stack_base, I32 stack_min, I32 stack_max, I
 STATIC void	S_exec_failed(pTHX_ const char *cmd, int fd, int do_report);
 #define PERL_ARGS_ASSERT_EXEC_FAILED	\
 	assert(cmd)
-STATIC bool	S_ingroup(pTHX_ Gid_t testgid, bool effective)
-			__attribute__warn_unused_result__;
-
 STATIC bool	S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, PerlIO *saveifp, PerlIO *saveofp, int savefd, char savetype, int writing, bool was_fdopen, const char *type);
 #define PERL_ARGS_ASSERT_OPENN_CLEANUP	\
 	assert(gv); assert(io); assert(mode); assert(oname)
@@ -4083,6 +4087,11 @@ STATIC IO *	S_openn_setup(pTHX_ GV *gv, char *mode, PerlIO **saveifp, PerlIO **s
 #define PERL_ARGS_ASSERT_OPENN_SETUP	\
 	assert(gv); assert(mode); assert(saveifp); assert(saveofp); assert(savefd); assert(savetype)
 #endif
+#if defined(PERL_IN_DOIO_C) && !defined(DOSISH)
+STATIC bool	S_ingroup(pTHX_ Gid_t testgid, bool effective)
+			__attribute__warn_unused_result__;
+
+#endif
 #if defined(PERL_IN_DOOP_C)
 STATIC I32	S_do_trans_complex(pTHX_ SV * const sv)
 			__attribute__warn_unused_result__;
@@ -4631,9 +4640,6 @@ STATIC I32	S_amagic_cmp_locale(pTHX_ SV *const str1, SV *const str2);
 STATIC OP*	S_doform(pTHX_ CV *cv, GV *gv, OP *retop);
 #define PERL_ARGS_ASSERT_DOFORM	\
 	assert(cv); assert(gv)
-STATIC SV *	S_space_join_names_mortal(pTHX_ char *const *array);
-#define PERL_ARGS_ASSERT_SPACE_JOIN_NAMES_MORTAL	\
-	assert(array)
 #endif
 #if defined(PERL_IN_REGCOMP_C)
 STATIC void	S__append_range_to_invlist(pTHX_ SV* const invlist, const UV start, const UV end);
@@ -5574,12 +5580,16 @@ PERL_CALLCONV const char*	Perl_quadmath_format_single(const char* format);
 PERL_CALLCONV char*	Perl_my_setlocale(pTHX_ int category, const char* locale)
 			__attribute__pure__;
 
+PERL_CALLCONV int	win32_async_check(pTHX);
 PERL_CALLCONV_NO_RET void	win32_croak_not_implemented(const char * fname)
 			__attribute__noreturn__;
 #define PERL_ARGS_ASSERT_WIN32_CROAK_NOT_IMPLEMENTED	\
 	assert(fname)
 
 #endif
+#if defined(WIN32) && defined(USE_ITHREADS)
+PERL_CALLCONV void	win32_wait_for_children(pTHX);
+#endif
 #if defined(WIN32) || defined(__SYMBIAN32__) || defined(VMS)
 PERL_CALLCONV int	Perl_do_aspawn(pTHX_ SV* really, SV** mark, SV** sp);
 #define PERL_ARGS_ASSERT_DO_ASPAWN	\
diff --git a/win32/Makefile b/win32/Makefile
index f6d8fb5..84b1f09 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -3,6 +3,8 @@
 # Supported compilers:
 #	Microsoft Visual C++ 6.0 or later
 #	Windows SDK 64-bit compiler and tools
+#	Intel C Compiler (requires Visual C++ or Windows SDK)
+#
 #
 # This is set up to build a perl.exe that runs off a shared library
 # (perl523.dll).  Also makes individual DLLs for the XS extensions.
@@ -133,6 +135,11 @@ CCTYPE		= MSVC60
 #__ICC		= define
 
 #
+# If you are using the unsupported Clang Compiler uncomment this
+#
+#CLANG	= define
+
+#
 # Uncomment this if you want to build everything in C++ mode
 #
 #USE_CPLUSPLUS	= define
@@ -318,6 +325,12 @@ BUILDOPT	= $(BUILDOPT) -DPERL_IMPLICIT_SYS
 PROCESSOR_ARCHITECTURE	= x86
 !ENDIF
 
+!IF "$(CLANG)" != "" && "$(CLANG)" != "undef"
+__clang__= define
+!ELSE
+__clang__= undef
+!ENDIF
+
 !IF "$(WIN64)" == ""
 # When we are running from a 32bit cmd.exe on AMD64 then
 # PROCESSOR_ARCHITECTURE is set to x86 and PROCESSOR_ARCHITEW6432
@@ -338,6 +351,36 @@ WIN64			= undef
 USE_64_BIT_INT	= define
 !ENDIF
 
+!IF "$(__clang__)" == "define"
+#you csn't change VC headers/libs versions to build XS with clang-cl builds
+#like you can with plain VC
+!IF "$(CCTYPE)" == "MSVC60"
+EXTRACFLAGS	= -fmsc-version=1200
+!ELSE IF "$(CCTYPE)" == "MSVC70" || "$(CCTYPE)" == "MSVC70FREE"
+#this technically wrong since it doesn't separate msvcr70.dll CRT from
+#msvcr71.dll, but perl has no code that cares about 1300 vs 1310
+EXTRACFLAGS	= -fmsc-version=1300
+!ELSE IF "$(CCTYPE)" == "SDK2003SP1" || "$(CCTYPE)" == "MSVC80" || "$(CCTYPE)" == "MSVC80FREE"
+#SDK2003SP1 for Win64 I think uses msvcrt.dll which has known IOINFO struct size
+#but setting the version to 1400 causes the WIN32_DYN_IOINFO_SIZE code to be used
+#which is slightly less efficint since PSDK and VC2005 can't be separated by
+#CC version number
+EXTRACFLAGS	= -fmsc-version=1400
+!ELSE IF "$(CCTYPE)" == "MSVC90" || "$(CCTYPE)" == "MSVC90FREE"
+EXTRACFLAGS	= -fmsc-version=1500
+!ELSE IF "$(CCTYPE)" == "MSVC100" || "$(CCTYPE)" == "MSVC100FREE"
+EXTRACFLAGS	= -fmsc-version=1600
+!ELSE IF "$(CCTYPE)" == "MSVC110" || "$(CCTYPE)" == "MSVC110FREE"
+EXTRACFLAGS	= -fmsc-version=1700
+!ELSE IF "$(CCTYPE)" == "MSVC120" || "$(CCTYPE)" == "MSVC120FREE"
+EXTRACFLAGS	= -fmsc-version=1800
+!ELSE
+!ERROR unknown CCTYPE
+!ENDIF
+!ELSE
+EXTRACFLAGS	=
+!ENDIF
+
 # Treat 64-bit MSVC60 (doesn't really exist) as SDK2003SP1 because
 # both link against MSVCRT.dll (which is part of Windows itself) and
 # not against a compiler specific versioned runtime.
@@ -424,7 +467,11 @@ INST_HTML	= $(INST_TOP)$(INST_VER)\html
 #
 
 !IF "$(__ICC)" != "define"
+!IF "$(__clang__)" == "define"
+CC		= clang-cl
+!ELSE
 CC		= cl
+!ENDIF
 LINK32		= link
 !ELSE
 CC		= icl
@@ -527,8 +574,8 @@ LIBBASEFILES    = $(LIBBASEFILES) bufferoverflowU.lib
 
 LIBFILES	= $(LIBBASEFILES) $(LIBC)
 
-#EXTRACFLAGS	= -nologo -GF -W4 -wd4127 -wd4706
-EXTRACFLAGS	= -nologo -GF -W3
+#EXTRACFLAGS	= $(EXTRACFLAGS) -nologo -GF -W4 -wd4127 -wd4706
+EXTRACFLAGS	= $(EXTRACFLAGS) -nologo -GF -W3
 !IF "$(__ICC)" == "define"
 EXTRACFLAGS	= $(EXTRACFLAGS) -Qstd=c99
 !ENDIF
@@ -844,6 +891,16 @@ CFG_VARS	=					\
 		"ccflags=$(EXTRACFLAGS) $(OPTIMIZE:"=\") $(DEFINES) $(BUILDOPT)"	\
 		"usecplusplus=$(USE_CPLUSPLUS)"		\
 		"cf_email=$(EMAIL)"	 		\
+!IF "$(__clang__)" == "define"
+		"d_attribute_deprecated=define"		\
+		"d_attribute_format=define"		\
+		"d_attribute_malloc=define"		\
+		"d_attribute_nonnull=define"		\
+		"d_attribute_noreturn=define"		\
+		"d_attribute_pure=define"		\
+		"d_attribute_unused=define"		\
+		"d_attribute_warn_unused_result=define"	\
+!ENDIF
 		"d_mymalloc=$(PERL_MALLOC)"		\
 		"libs=$(LIBFILES)"			\
 		"incpath=$(CCINCDIR:"=\")"		\
@@ -932,6 +989,14 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #undef USE_64_BIT_INT>>$@
 	@echo #undef Size_t_size>>$@
 	@echo #undef USE_CPLUSPLUS>>$@
+	@echo #undef HASATTRIBUTE_DEPRECATED>>$@
+	@echo #undef HASATTRIBUTE_FORMAT>>$@
+	@echo #undef HASATTRIBUTE_MALLOC>>$@
+	@echo #undef HASATTRIBUTE_NONNULL>>$@
+	@echo #undef HASATTRIBUTE_NORETURN>>$@
+	@echo #undef HASATTRIBUTE_PURE>>$@
+	@echo #undef HASATTRIBUTE_UNUSED>>$@
+	@echo #undef HASATTRIBUTE_WARN_UNUSED_RESULT>>$@
 !IF "$(USE_LARGE_FILES)"=="define"
 	@echo #define Off_t __int64>>$@
 	@echo #define LSEEKSIZE ^8>>$@
@@ -983,6 +1048,19 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #define UVXf "lX">>$@
 	@echo #undef USE_64_BIT_INT>>$@
 !ENDIF
+!IF "$(__clang__)"=="define"
+#clang 1.0 docs say all of these are "ignored" or "supported"
+#ignored is as good as supported, no need know clang version and
+#avoid more conditionals based on clang version
+	@echo #define HASATTRIBUTE_DEPRECATED>>$@
+	@echo #define HASATTRIBUTE_FORMAT>>$@
+	@echo #define HASATTRIBUTE_MALLOC>>$@
+	@echo #define HASATTRIBUTE_NONNULL>>$@
+	@echo #define HASATTRIBUTE_NORETURN>>$@
+	@echo #define HASATTRIBUTE_PURE>>$@
+	@echo #define HASATTRIBUTE_UNUSED>>$@
+	@echo #define HASATTRIBUTE_WARN_UNUSED_RESULT>>$@
+!ENDIF
 !IF "$(USE_CPLUSPLUS)"=="define"
 	@echo #define USE_CPLUSPLUS>>$@
 !ELSE
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 2749d6b..e7b0c3f 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -4,6 +4,8 @@
 #	Microsoft Visual C++ 6.0 or later
 #	MinGW with gcc-3.4.5 or later
 #	Windows SDK 64-bit compiler and tools
+#	Intel C Compiler (requires Visual C++ or Windows SDK)
+#
 #
 # This is set up to build a perl.exe that runs off a shared library
 # (perl523.dll).  Also makes individual DLLs for the XS extensions.
@@ -153,6 +155,13 @@ CCTYPE		*= GCC
 #__ICC		*= define
 
 #
+# If you are using the unsupported Clang Compiler uncomment this.
+# You still must set CCTYPE above to GCC (unimplemented) or a particular
+# Visual C version, which says which C linker, libraries, and C headers to use.
+#
+#CLANG	= define
+
+#
 # Uncomment this if you want to build everything in C++ mode
 #
 #USE_CPLUSPLUS	*= define
@@ -349,6 +358,12 @@ PROCESSOR_ARCHITECTURE *= x86
 PROCESSOR_ARCHITECTURE	= x86
 .ENDIF
 
+.IF "$(CLANG)" != "" && "$(CLANG)" != "undef"
+__clang__	= define
+.ELSE
+__clang__	= undef
+.ENDIF
+
 .IF "$(WIN64)" == ""
 # When we are running from a 32bit cmd.exe on AMD64 then
 # PROCESSOR_ARCHITECTURE is set to x86 and PROCESSOR_ARCHITEW6432
@@ -367,6 +382,38 @@ WIN64			= undef
 USE_64_BIT_INT	= define
 .ENDIF
 
+.IF "$(__clang__)" == "define"
+#you csn't change VC headers/libs versions to build XS with clang-cl builds
+#like you can with plain VC
+.IF "$(CCTYPE)" == "MSVC60"
+EXTRACFLAGS	= -fmsc-version=1200
+.ELIF "$(CCTYPE)" == "MSVC70" || "$(CCTYPE)" == "MSVC70FREE"
+#this technically wrong since it doesn't separate msvcr70.dll CRT from
+#msvcr71.dll, but perl has no code that cares about 1300 vs 1310
+EXTRACFLAGS	= -fmsc-version=1300
+.ELIF "$(CCTYPE)" == "SDK2003SP1" || "$(CCTYPE)" == "MSVC80" || "$(CCTYPE)" == "MSVC80FREE"
+#SDK2003SP1 for Win64 I think uses msvcrt.dll which has known IOINFO struct size
+#but setting the version to 1400 causes the WIN32_DYN_IOINFO_SIZE code to be used
+#which is slightly less efficint since PSDK and VC2005 can't be separated by
+#CC version number
+EXTRACFLAGS	= -fmsc-version=1400
+.ELIF "$(CCTYPE)" == "MSVC90" || "$(CCTYPE)" == "MSVC90FREE"
+EXTRACFLAGS	= -fmsc-version=1500
+.ELIF "$(CCTYPE)" == "MSVC100" || "$(CCTYPE)" == "MSVC100FREE"
+EXTRACFLAGS	= -fmsc-version=1600
+.ELIF "$(CCTYPE)" == "MSVC110" || "$(CCTYPE)" == "MSVC110FREE"
+EXTRACFLAGS	= -fmsc-version=1700
+.ELIF "$(CCTYPE)" == "MSVC120" || "$(CCTYPE)" == "MSVC120FREE"
+EXTRACFLAGS	= -fmsc-version=1800
+.ELSE
+.INIT::
+	@echo Unknown CCTYPE "$(CCTYPE)" for Clang
+	@exit 1
+.ENDIF
+.ELSE
+EXTRACFLAGS	=
+.ENDIF
+
 # Treat 64-bit MSVC60 (doesn't really exist) as SDK2003SP1 because
 # both link against MSVCRT.dll (which is part of Windows itself) and
 # not against a compiler specific versioned runtime.
@@ -503,7 +550,6 @@ OPTIMIZE	= -s -O2
 LINK_DBG	= -s
 .ENDIF
 
-EXTRACFLAGS	=
 .IF "$(USE_CPLUSPLUS)" == "define"
 EXTRACFLAGS	+= $(CXX_FLAG)
 .ENDIF
@@ -547,7 +593,11 @@ PREMSVC80	= undef
 .ENDIF
 
 .IF "$(__ICC)" != "define"
+.IF "$(__clang__)" == "define"
+CC		= clang-cl
+.ELSE
 CC		= cl
+.ENDIF
 LINK32		= link
 .ELSE
 CC		= icl
@@ -646,7 +696,7 @@ LIBBASEFILES    += bufferoverflowU.lib
 
 LIBFILES	= $(LIBBASEFILES) $(LIBC)
 
-EXTRACFLAGS	= -nologo -GF -W3
+EXTRACFLAGS	+= -nologo -GF -W3
 .IF "$(__ICC)" == "define"
 EXTRACFLAGS	+= -Qstd=c99
 .ENDIF
@@ -1042,6 +1092,19 @@ CFG_VARS	=					\
 		ARCHPREFIX=$(ARCHPREFIX)	~	\
 		WIN64=$(WIN64)
 
+#these are turned on for GCC in perl.h with GCC version checks
+.IF "$(__clang__)" == "define"
+CFG_VARS	+=					\
+						~	\
+		d_attribute_deprecated=define	~	\
+		d_attribute_format=define	~	\
+		d_attribute_malloc=define	~	\
+		d_attribute_nonnull=define	~	\
+		d_attribute_noreturn=define	~	\
+		d_attribute_pure=define		~	\
+		d_attribute_unused=define	~	\
+		d_attribute_warn_unused_result=define
+.ENDIF
 #
 # Top targets
 #
@@ -1186,7 +1249,15 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
 	echo #undef NVff&& \
 	echo #undef NVgf&& \
 	echo #undef USE_LONG_DOUBLE&& \
-	echo #undef USE_CPLUSPLUS)>> config.h
+	echo #undef USE_CPLUSPLUS&& \
+	echo #undef HASATTRIBUTE_DEPRECATED&& \
+	echo #undef HASATTRIBUTE_FORMAT&& \
+	echo #undef HASATTRIBUTE_MALLOC&& \
+	echo #undef HASATTRIBUTE_NONNULL&& \
+	echo #undef HASATTRIBUTE_NORETURN&& \
+	echo #undef HASATTRIBUTE_PURE&& \
+	echo #undef HASATTRIBUTE_UNUSED&& \
+	echo #undef HASATTRIBUTE_WARN_UNUSED_RESULT)>> config.h
 .IF "$(USE_LARGE_FILES)"=="define"
 	@(echo #define Off_t $(INT64)&& \
 	echo #define LSEEKSIZE ^8&& \
@@ -1289,6 +1360,19 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
 	echo #define NVgf "g"&& \
 	echo #undef USE_LONG_DOUBLE)>> config.h
 .ENDIF
+.IF "$(__clang__)"=="define"
+#clang 1.0 docs say all of these are "ignored" or "supported"
+#ignored is as good as supported, no need know clang version and
+#avoid more conditionals based on clang version
+	@(echo #define HASATTRIBUTE_DEPRECATED&& \
+	echo #define HASATTRIBUTE_FORMAT&& \
+	echo #define HASATTRIBUTE_MALLOC&& \
+	echo #define HASATTRIBUTE_NONNULL&& \
+	echo #define HASATTRIBUTE_NORETURN&& \
+	echo #define HASATTRIBUTE_PURE&& \
+	echo #define HASATTRIBUTE_UNUSED&& \
+	echo #define HASATTRIBUTE_WARN_UNUSED_RESULT)>> config.h
+.ENDIF
 .IF "$(USE_CPLUSPLUS)"=="define"
 	@(echo #define USE_CPLUSPLUS&& \
 	echo #endif)>> config.h
diff --git a/win32/perlhost.h b/win32/perlhost.h
index 7a0c3b3..98492b3 100644
--- a/win32/perlhost.h
+++ b/win32/perlhost.h
@@ -2065,7 +2065,7 @@ CPerlHost::CPerlHost(CPerlHost& host)
     /* duplicate environment info */
     LPSTR lpPtr;
     DWORD dwIndex = 0;
-    while(lpPtr = host.GetIndex(dwIndex))
+    while((lpPtr = host.GetIndex(dwIndex)))
 	Add(lpPtr);
 }
 
diff --git a/win32/perllib.c b/win32/perllib.c
index 0e44a24..1d5005a 100644
--- a/win32/perllib.c
+++ b/win32/perllib.c
@@ -34,7 +34,7 @@ EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
 static void
 xs_init(pTHX)
 {
-    char *file = __FILE__;
+    const char *file = __FILE__;
     dXSUB_SYS;
     newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
     /* other similar records will be included from "perllibst.h" */
diff --git a/win32/win32.c b/win32/win32.c
index 2b883a2..0988cc3 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -137,7 +137,9 @@ static int	terminate_process(DWORD pid, HANDLE process_handle, int sig);
 static int	my_killpg(int pid, int sig);
 static int	my_kill(int pid, int sig);
 static void	out_of_memory(void);
+#ifdef _DEBUG
 static char*	wstr_to_str(const wchar_t* wstr);
+#endif
 static long	filetime_to_clock(PFILETIME ft);
 static BOOL	filetime_from_time(PFILETIME ft, time_t t);
 static char*	create_command_line(char *cname, STRLEN clen,
@@ -1670,6 +1672,7 @@ win32_croak_not_implemented(const char * fname)
 /* Converts a wide character (UTF-16) string to the Windows ANSI code page,
  * potentially using the system's default replacement character for any
  * unrepresentable characters. The caller must free() the returned string. */
+#ifdef _DEBUG
 static char*
 wstr_to_str(const wchar_t* wstr)
 {
@@ -1684,6 +1687,7 @@ wstr_to_str(const wchar_t* wstr)
                         str, len, NULL, &used_default);
     return str;
 }
+#endif
 
 /* The win32_ansipath() function takes a Unicode filename and converts it
  * into the current Windows codepage. If some characters cannot be mapped,
@@ -2044,11 +2048,11 @@ win32_uname(struct utsname *name)
     }
 
     /* release */
-    sprintf(name->release, "%d.%d",
+    sprintf(name->release, "%u.%u",
             g_osver.dwMajorVersion, g_osver.dwMinorVersion);
 
     /* version */
-    sprintf(name->version, "Build %d",
+    sprintf(name->version, "Build %u",
             g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT
             ? g_osver.dwBuildNumber : (g_osver.dwBuildNumber & 0xffff));
     if (g_osver.szCSDVersion[0]) {
@@ -2151,7 +2155,7 @@ sig_terminate(pTHX_ int sig)
     exit(sig);
 }
 
-DllExport int
+int
 win32_async_check(pTHX)
 {
     MSG msg;
@@ -2596,10 +2600,6 @@ extern int convert_errno_to_wsa_error(int err); /* in win32sck.c */
 DllExport char *
 win32_strerror(int e)
 {
-#if !defined __MINGW32__      /* compiler intolerance */
-    extern int sys_nerr;
-#endif
-
     if (e < 0 || e > sys_nerr) {
         dTHXa(NULL);
 	if (e < 0)
@@ -2942,7 +2942,6 @@ do_popen(const char *mode, const char *command, IV narg, SV **args) {
     int ourmode;
     int childpid;
     DWORD nhandle;
-    int lock_held = 0;
     const char **args_pvs = NULL;
 
     /* establish which ends read and write */
@@ -4213,7 +4212,7 @@ void
 Perl_init_os_extras(void)
 {
     dTHXa(NULL);
-    char *file = __FILE__;
+    const char *file = __FILE__;
 
     /* Initialize Win32CORE if it has been statically linked. */
 #ifndef PERL_IS_MINIPERL
diff --git a/win32/win32.h b/win32/win32.h
index 3b35b6c..001938d 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -263,7 +263,7 @@ PERL_STATIC_INLINE
 double S_Infinity() {
     /* this is a real C literal which can get further constant folded
        unlike using HUGE_VAL/_HUGE which are data symbol imports from the CRT
-       and therefore can not by folded by VC, an example of constant
+       and therefore can not be folded by VC, an example of constant
        folding INF is creating -INF */
     return (DBL_MAX+DBL_MAX);
 }
@@ -391,7 +391,6 @@ typedef struct {
 
 DllExport void		win32_get_child_IO(child_IO_table* ptr);
 DllExport HWND		win32_create_message_window(void);
-DllExport int		win32_async_check(pTHX);
 
 extern int		my_fclose(FILE *);
 extern char *		win32_get_privlib(const char *pl, STRLEN *const len);
@@ -529,7 +528,6 @@ struct interp_intern {
 #define w32_showwindow	(PL_sys_intern.thr_intern.Wshowwindow)
 
 #ifdef USE_ITHREADS
-void win32_wait_for_children(pTHX);
 #  define PERL_WAIT_FOR_CHILDREN win32_wait_for_children(aTHX)
 #endif
 
diff --git a/win32/win32io.c b/win32/win32io.c
index 00f5bb8..89a949d 100644
--- a/win32/win32io.c
+++ b/win32/win32io.c
@@ -304,7 +304,6 @@ PerlIOWin32_close(pTHX_ PerlIO *f)
  PerlIOWin32 *s = PerlIOSelf(f,PerlIOWin32);
  if (s->refcnt == 1)
   {
-   IV code = 0;	
 #if 0
    /* This does not do pipes etc. correctly */	
    if (!CloseHandle(s->h))
diff --git a/win32/win32sck.c b/win32/win32sck.c
index 3f97241..a2afdff 100644
--- a/win32/win32sck.c
+++ b/win32/win32sck.c
@@ -340,7 +340,7 @@ start_sockets(void)
      * cleaned up at exit.
      */
     version = 0x2;
-    if(ret = WSAStartup(version, &retdata))
+    if((ret = WSAStartup(version, &retdata)))
 	Perl_croak_nocontext("Unable to locate winsock library!\n");
     if(retdata.wVersion != version)
 	Perl_croak_nocontext("Could not find version 2.0 of winsock dll\n");
diff --git a/win32/wince.c b/win32/wince.c
index 1b58d40..e773aa2 100644
--- a/win32/wince.c
+++ b/win32/wince.c
@@ -2649,7 +2649,7 @@ void
 Perl_init_os_extras(void)
 {
     dTHX;
-    char *file = __FILE__;
+    const char *file = __FILE__;
     dXSUB_SYS;
 
     w32_perlshell_tokens = NULL;
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Sep 14, 2015

From @tonycoz

On Wed Sep 09 13​:35​:46 2015, bulk88 wrote​:

No patches were posted, resending.

This mostly makes sense to me.

I do wonder why you're using two separate macros for clang support​:

+!IF "$(CLANG)" != "" && "$(CLANG)" != "undef"
+__clang__= define
+!ELSE
+__clang__= undef
+!ENDIF

where other macros are handled by setting defaults only if the macro is undefined​:

!IF "$(USE_64_BIT_INT)" == ""
USE_64_BIT_INT = undef
!ENDIF

win32.c(2048,13) : warning​: format specifies type 'int' but the argument has
type 'DWORD' (aka 'unsigned long') [-Wformat]
g_osver.dwMajorVersion, g_osver.dwMinorVersion);
^~~~~~~~~~~~~~~~~~~~~~
win32.c(2048,37) : warning​: format specifies type 'int' but the argument has
type 'DWORD' (aka 'unsigned long') [-Wformat]
g_osver.dwMajorVersion, g_osver.dwMinorVersion);
^~~~~~~~~~~~~~~~~~~~~~
win32.c(2052,13) : warning​: format specifies type 'int' but the argument has
type 'DWORD' (aka 'unsigned long') [-Wformat]
g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT

change %d to %u, negative version numbers dont make sense, warning still
remains since the compiler still warns that "unsigned long" isnt
"unsigned int", but they are the same on Win32/Win64, so it is a possible
clang bug. This code will never run on unix so portability doesn't matter.

It's not a bug, they may be different types, but the code is still incorrect.

Splitting part 3 into pieces wouldn't hurt.

Tony

@p5pRT
Copy link
Author

p5pRT commented Sep 14, 2015

The RT System itself - Status changed from 'new' to 'open'

@toddr
Copy link
Member

toddr commented Feb 13, 2020

@bulk88 these patch no longer applies cleanly. I'm putting words in his mouth, but I think @tonycoz was ok with some of this so it might be worth pursuing. Could you please rebase and submit this as a pull request?

@toddr toddr closed this as completed Feb 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants