summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-08-06 15:24:48 -0700
committerReid Kleckner <rnk@google.com>2019-08-06 15:24:48 -0700
commite62fca4a4a7f10e4f1e0506f2cfdb6c1c4b7cf3a (patch)
tree37ebb47eda8fb373f0a2000afcc2d9a3fb6b8bde
parentda0dcccc44f11809d1241fcd52b4c0e25146d2a2 (diff)
downloadnasm-e62fca4a4a7f10e4f1e0506f2cfdb6c1c4b7cf3a.tar.gz
Fix extern_inline for MSVC and clang-cl
Prior to this change, no inline function bodies would be provided for MSVC. This change fixes that, so nasm will be slightly faster. With clang-cl, however, there would be LNK4006 warnings if the compiler chooses not to inline the ilog2 functions. The easiest way to observe this is with `nmake /f Mkfiles/msvc.mak CC=clang-cl DEBUG=1`. This disables inlining, and I see this at the end of the link: ilog2.obj : warning LNK4006: ilog2_32 already defined in outmacho.obj; second definition ignored ilog2.obj : warning LNK4006: ilog2_64 already defined in eval.obj; second definition ignored ilog2.obj : warning LNK4006: alignlog2_32 already defined in outmacho.obj; second definition ignored When additional instrumentation (-fprofile-instr-generate) is enabled, the warning can become an error, as we discovered in https://crbug.com/989745. MSVC and compilers pretending to be MSVC (clang-cl) implement inline in C with C++ semantics. In C++, inline functions are emitted by the compiler whenever they are needed and the linker discards duplicate inline function definitions. This change adds a new HAVE_MSVC_INLINE macro and adjusts the ifdefs to handle this mode. I chose to keep ilog2.c as part of the build, and to have it emit duplicate definitions of all the inline functions. An alternative solution would be to exclude it from the build, but I felt it was best to solve this in source code instead of the build system. R=dalecurtis@chromium.org, davidben@chromium.org Chromium-specific: I reran find_patches.py with some modifications to make it work on Windows. Change-Id: I21011ed4f619f920c53f7cfc3afaa32dc2c0ff4e
-rw-r--r--README.patches44
-rwxr-xr-xfind_patches.py3
-rw-r--r--include/compiler.h7
-rw-r--r--include/ilog2.h6
4 files changed, 54 insertions, 6 deletions
diff --git a/README.patches b/README.patches
index 9c630382..dffdbc0e 100644
--- a/README.patches
+++ b/README.patches
@@ -26,9 +26,9 @@ Affects:
nasmlib/ver.c
------------------------------------------------------------------
-commit e5417246fc34b430f241f055b8b9570f5d9ab2c3
+commit 4ee6a69ce33be1e96fd3c44a6e3ae3d8177453da
Author: Dale Curtis <dalecurtis@chromium.org>
-Date: Mon Nov 19 13:50:47 2018 -0800
+Date: Mon Nov 19 13:52:05 2018 -0800
Remove uses of time(NULL) for build determism.
@@ -37,7 +37,45 @@ Date: Mon Nov 19 13:50:47 2018 -0800
BUG=766721
TEST=none
+ Change-Id: I88c11d052aef8a9c4e48b3b976ad432f3b008dd6
+
Affects:
- output/outcoff.c
asm/nasm.c
+ output/outcoff.c
+
+------------------------------------------------------------------
+commit dff67a9842e4ab6699598d75691a630df090e7f5
+Author: Reid Kleckner <rnk@google.com>
+Date: Tue Aug 6 15:16:16 2019 -0700
+
+ Fix extern_inline for MSVC and clang-cl
+
+ Prior to this change, no inline function bodies would be provided for
+ MSVC. This change fixes that, so nasm will be slightly faster.
+
+ With clang-cl, however, there would be LNK4006 warnings if the compiler
+ chooses not to inline the ilog2 functions. The easiest way to observe
+ this is with `nmake /f Mkfiles/msvc.mak CC=clang-cl DEBUG=1`. This
+ disables inlining, and I see this at the end of the link:
+ ilog2.obj : warning LNK4006: ilog2_32 already defined in outmacho.obj; second definition ignored
+ ilog2.obj : warning LNK4006: ilog2_64 already defined in eval.obj; second definition ignored
+ ilog2.obj : warning LNK4006: alignlog2_32 already defined in outmacho.obj; second definition ignored
+
+ When additional instrumentation (-fprofile-instr-generate) is enabled,
+ the warning can become an error, as we discovered in
+ https://crbug.com/989745.
+
+ MSVC and compilers pretending to be MSVC (clang-cl) implement inline in
+ C with C++ semantics. In C++, inline functions are emitted by the
+ compiler whenever they are needed and the linker discards duplicate
+ inline function definitions. This change adds a new HAVE_MSVC_INLINE
+ macro and adjusts the ifdefs to handle this mode. I chose to keep
+ ilog2.c as part of the build, and to have it emit duplicate definitions
+ of all the inline functions. An alternative solution would be to exclude
+ it from the build, but I felt it was best to solve this in source code
+ instead of the build system.
+
+Affects:
+ include/compiler.h
+ include/ilog2.h
diff --git a/find_patches.py b/find_patches.py
index f579fcdc..3a9f87c0 100755
--- a/find_patches.py
+++ b/find_patches.py
@@ -255,7 +255,8 @@ def write_patches_file(origin_branch, output_file):
print("\nAffects:", file=output_file)
# TODO(liberato): maybe add the lines that were affected.
for file in sorted(sha1ToFiles[sha1]):
- print(" " + os.path.relpath(file, wd), file=output_file)
+ relfile = os.path.relpath(file, wd).replace('\\', '/')
+ print(" " + relfile, file=output_file)
print(file=output_file)
log("Done")
diff --git a/include/compiler.h b/include/compiler.h
index 4178c98e..fa63fea0 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -224,6 +224,11 @@ size_t strnlen(const char *s, size_t maxlen);
# elif defined(__GNUC_GNU_INLINE__)
/* Some other compiler implementing only GNU inline semantics? */
# define HAVE_GNU_INLINE
+# elif defined(_MSC_VER)
+/* In MSVC and clang when it is pretending to be MSVC, inline behaves it does in
+ * C++.
+ */
+# define HAVE_MSVC_INLINE
# elif defined(__STDC_VERSION__)
# if __STDC_VERSION__ >= 199901L
# define HAVE_STDC_INLINE
@@ -236,6 +241,8 @@ size_t strnlen(const char *s, size_t maxlen);
#elif defined(HAVE_GNU_INLINE)
# define extern_inline extern inline
# define inline_prototypes
+#elif defined(HAVE_MSVC_INLINE)
+# define extern_inline inline
#else
# define inline_prototypes
#endif
diff --git a/include/ilog2.h b/include/ilog2.h
index 3a828be8..295ca3f6 100644
--- a/include/ilog2.h
+++ b/include/ilog2.h
@@ -38,8 +38,10 @@
#include <limits.h>
#ifdef ILOG2_C /* For generating the out-of-line functions */
-# undef extern_inline
-# define extern_inline
+# ifndef HAVE_MSVC_INLINE
+# undef extern_inline
+# define extern_inline
+# endif
# define inline_prototypes
#endif