Add SpectreMitigation attribute for msvs

This CL allows gyp to recognize the SpectreMitigation msvs_attribute
and add it to the generated vcxproj file for MSBuild.
Possible values for the attribute are Spectre, SpectreLoad,
SpectreLoadCF, and false.

The /Qspectre compiler option is not enough to add
full Spectre mitigation, because even though it causes MSBuild
to add additional instructions to the generated object files,
it does not cause MSBuild to link against Spectre-mitigated
libraries provided by Visual Studio.

Change-Id: I8294395659354f3ce60a355622da4b026abcceba
Reviewed-on: https://chromium-review.googlesource.com/c/external/gyp/+/4265144
Reviewed-by: Mark Mentovai <mark@chromium.org>
diff --git a/pylib/gyp/easy_xml_test.py b/pylib/gyp/easy_xml_test.py
index a1fdb18..c3be446 100755
--- a/pylib/gyp/easy_xml_test.py
+++ b/pylib/gyp/easy_xml_test.py
@@ -81,6 +81,7 @@
                        '\'Debug|Win32\'" Label="Configuration">'
           '<ConfigurationType>Application</ConfigurationType>'
           '<CharacterSet>Unicode</CharacterSet>'
+          '<SpectreMitigation>SpectreLoadCF</SpectreMitigation>'
         '</PropertyGroup>'
       '</Project>')
 
@@ -96,7 +97,8 @@
             {'Condition': "'$(Configuration)|$(Platform)'=='Debug|Win32'",
              'Label': 'Configuration'},
             ['ConfigurationType', 'Application'],
-            ['CharacterSet', 'Unicode']
+            ['CharacterSet', 'Unicode'],
+            ['SpectreMitigation', 'SpectreLoadCF']
           ]
         ])
     self.assertEqual(xml, target)
diff --git a/pylib/gyp/generator/msvs.py b/pylib/gyp/generator/msvs.py
index 263b312..2278c16 100644
--- a/pylib/gyp/generator/msvs.py
+++ b/pylib/gyp/generator/msvs.py
@@ -2740,6 +2740,10 @@
     config_type = msbuild_attributes.get('ConfigurationType')
     _AddConditionalProperty(properties, condition, 'ConfigurationType',
                             config_type)
+    spectre_mitigation = msbuild_attributes.get('SpectreMitigation')
+    if spectre_mitigation:
+      _AddConditionalProperty(properties, condition, 'SpectreMitigation',
+                              spectre_mitigation)
     if config_type == 'Driver':
       _AddConditionalProperty(properties, condition, 'DriverType', 'WDM')
       _AddConditionalProperty(properties, condition, 'TargetVersion',
@@ -2821,6 +2825,8 @@
       msbuild_attributes[a] = _ConvertMSVSCharacterSet(msvs_attributes[a])
     elif a == 'ConfigurationType':
       msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a])
+    elif a == 'SpectreMitigation':
+      msbuild_attributes[a] = msvs_attributes[a]
     else:
       print('Warning: Do not know how to convert MSVS attribute ' + a)
   return msbuild_attributes
diff --git a/test/win/compiler-flags/spectre-mitigation.gyp b/test/win/compiler-flags/spectre-mitigation.gyp
new file mode 100644
index 0000000..dad9cbd
--- /dev/null
+++ b/test/win/compiler-flags/spectre-mitigation.gyp
@@ -0,0 +1,44 @@
+# Copyright (c) 2023 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+    {
+      'target_name': 'test_sm_notset',
+      'product_name': 'test_sm_notset',
+      'type': 'executable',
+      'msvs_configuration_attributes': {
+        'SpectreMitigation': 'false'
+      },
+      'sources': ['hello.cc'],
+    },
+    {
+      'target_name': 'test_sm_spectre',
+      'product_name': 'test_sm_spectre',
+      'type': 'executable',
+      'msvs_configuration_attributes': {
+        'SpectreMitigation': 'Spectre'
+      },
+      'sources': ['hello.cc'],
+    },
+    {
+      'target_name': 'test_sm_spectre_load',
+      'product_name': 'test_sm_spectre_load',
+      'type': 'executable',
+      'msvs_configuration_attributes': {
+        'SpectreMitigation': 'SpectreLoad'
+      },
+      'sources': ['hello.cc'],
+    },
+    {
+      'target_name': 'test_sm_spectre_load_cf',
+      'product_name': 'test_sm_spectre_load_cf',
+      'type': 'executable',
+      'msvs_configuration_attributes': {
+        'SpectreMitigation': 'SpectreLoadCF'
+      },
+      'sources': ['hello.cc'],
+    }
+  ]
+}