Enable warnings on Windows
diff --git a/.appveyor.yml b/.appveyor.yml
index 72e1337..93bcd17 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -13,7 +13,7 @@
 build_script:
  - mkdir build
  - cd build
- - cmake ..
+ - cmake -DNXT_USE_WERROR=1 ..
  - cmake --build .
 
  # TODO(cwallez@chromium.org) test on more than Debug.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fe73cc9..8ebdcdc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,7 @@
 set(NXT_DEFS "")
 set(NXT_INTERNAL_FLAGS "")
 set(NXT_INTERNAL_DEFS "")
+set(NXT_GENERATED_FLAGS "")
 
 if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
     list(APPEND NXT_DEFS "NXT_ENABLE_ASSERTS")
@@ -43,13 +44,24 @@
 
 if (MSVC)
     list(APPEND NXT_FLAGS "/std:c++14")
+    list(APPEND NXT_INTERNAL_FLAGS "/W4")
+    # Allow declarations hiding members as it is used all over NXT
+    list(APPEND NXT_INTERNAL_FLAGS "/wd4458")
+    list(APPEND NXT_INTERNAL_FLAGS "/wd4996") # Allow deprecated functions like strncpy
+
+    list(APPEND NXT_GENERATED_FLAGS "/wd4702") # Allow unreachable code
+    list(APPEND NXT_GENERATED_FLAGS "/wd4189") # Allow unused variable
+    
+    if(NXT_USE_WERROR)
+        list(APPEND NXT_INTERNAL_FLAGS "/WX")
+    endif()
 else()
     # Activate C++14 only on C++ files, not C files.
     list(APPEND NXT_FLAGS "$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-std=c++14>")
     list(APPEND NXT_FLAGS "-fPIC")
 
     list(APPEND NXT_INTERNAL_FLAGS "-Wall" "-Wextra")
-    list(APPEND NXT_GENERATED_FLAGS "-Wno-unused-variable")
+    list(APPEND NXT_GENERATED_FLAGS "-Wno-unused-variable" "-Wno-unused-function")
     if(NXT_USE_WERROR)
         list(APPEND NXT_INTERNAL_FLAGS "-Werror")
     endif()
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index e2ad4b2..d49f3d1 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -22,8 +22,23 @@
 function(add_nxt_sample target sources)
     add_executable(${target} ${sources})
     target_link_libraries(${target} sample_utils)
-    target_include_directories(${target} PRIVATE ${GLM_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+    target_include_directories(${target} SYSTEM PRIVATE ${GLM_INCLUDE_DIR})
+    target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
     NXTInternaltarget("examples" ${target})
+
+    # Suppress some warnings in our sample dependencies
+    if (MSVC)
+        # nonstandard extension used: nameless struct/union -- for GLM
+        set_property(TARGET ${target} APPEND PROPERTY COMPILE_OPTIONS "/wd4201")
+        # declaration hides global declaration -- for GLM
+        set_property(TARGET ${target} APPEND PROPERTY COMPILE_OPTIONS "/wd4459")
+        # = conversion possible loss of data -- for STB image
+        set_property(TARGET ${target} APPEND PROPERTY COMPILE_OPTIONS "/wd4244")
+        # declaration hides previous declaration -- for STB image
+        set_property(TARGET ${target} APPEND PROPERTY COMPILE_OPTIONS "/wd4456")
+        # declaration hides previous declaration -- for picojson
+        set_property(TARGET ${target} APPEND PROPERTY COMPILE_OPTIONS "/wd4706")
+    endif()
 endfunction()
 
 add_nxt_sample(CHelloTriangle CHelloTriangle.cpp)
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt
index 998a124..f311e28 100644
--- a/generator/CMakeLists.txt
+++ b/generator/CMakeLists.txt
@@ -62,10 +62,7 @@
     )
 
     NXTInternalTarget("${G_FOLDER}" ${G_LIB_NAME})
-    if (NOT MSVC)
-        target_compile_options(${G_LIB_NAME} PRIVATE "-Wno-unused-variable")
-        target_compile_options(${G_LIB_NAME} PRIVATE "-Wno-unused-function")
-    endif()
+    target_compile_options(${G_LIB_NAME} PRIVATE ${NXT_GENERATED_FLAGS})
 endfunction()
 
 set(GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
diff --git a/src/backend/BindGroupLayout.cpp b/src/backend/BindGroupLayout.cpp
index a757139..6837ebe 100644
--- a/src/backend/BindGroupLayout.cpp
+++ b/src/backend/BindGroupLayout.cpp
@@ -35,11 +35,10 @@
             return std::hash<unsigned long long>()(value.to_ullong());
         }
 
-
         // TODO(cwallez@chromium.org): see if we can use boost's hash combined or some equivalent
         // this currently assumes that size_t is 64 bits
         void CombineHashes(size_t* h1, size_t h2) {
-            *h1 ^= (h2 << 7) + (h2 >> (64 - 7)) + 0x304975;
+            *h1 ^= (h2 << 7) + (h2 >> (sizeof(size_t) * 8 - 7)) + 0x304975;
         }
 
         size_t HashBindingInfo(const BindGroupLayoutBase::LayoutBindingInfo& info) {
diff --git a/src/tests/unittests/validation/ValidationTest.cpp b/src/tests/unittests/validation/ValidationTest.cpp
index 8f80525..11835be 100644
--- a/src/tests/unittests/validation/ValidationTest.cpp
+++ b/src/tests/unittests/validation/ValidationTest.cpp
@@ -85,7 +85,7 @@
 
 void ValidationTest::OnBuilderErrorStatus(nxtBuilderErrorStatus status, const char* message, nxt::CallbackUserdata userdata1, nxt::CallbackUserdata userdata2) {
     auto* self = reinterpret_cast<ValidationTest*>(static_cast<uintptr_t>(userdata1));
-    size_t index = userdata2;
+    size_t index = static_cast<size_t>(userdata2);
 
     ASSERT_LT(index, self->expectations.size());