Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ _STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

// TRANSITION, non-_Ugly attribute tokens
#pragma push_macro("msvc")
#pragma push_macro("lifetimebound")
#undef msvc
#undef lifetimebound

#if _USE_STD_VECTOR_ALGORITHMS

_EXTERN_C
Expand Down Expand Up @@ -10003,8 +10009,9 @@ namespace ranges {
#endif // _HAS_CXX17

_EXPORT_STD template <class _Ty, class _Pr>
_NODISCARD constexpr pair<const _Ty&, const _Ty&> minmax(const _Ty& _Left, const _Ty& _Right, _Pr _Pred) noexcept(
noexcept(_DEBUG_LT_PRED(_Pred, _Right, _Left))) /* strengthened */ {
_NODISCARD constexpr pair<const _Ty&, const _Ty&> minmax(const _Ty& _Left _MSVC_LIFETIMEBOUND,
const _Ty& _Right _MSVC_LIFETIMEBOUND,
_Pr _Pred) noexcept(noexcept(_DEBUG_LT_PRED(_Pred, _Right, _Left))) /* strengthened */ {
// return pair(leftmost/smaller, rightmost/larger) of _Left and _Right
if (_DEBUG_LT_PRED(_Pred, _Right, _Left)) {
return {_Right, _Left};
Expand All @@ -10021,8 +10028,8 @@ _NODISCARD constexpr pair<_Ty, _Ty> minmax(initializer_list<_Ty> _Ilist, _Pr _Pr
}

_EXPORT_STD template <class _Ty>
_NODISCARD constexpr pair<const _Ty&, const _Ty&> minmax(const _Ty& _Left, const _Ty& _Right) noexcept(
noexcept(_Right < _Left)) /* strengthened */ {
_NODISCARD constexpr pair<const _Ty&, const _Ty&> minmax(const _Ty& _Left _MSVC_LIFETIMEBOUND,
const _Ty& _Right _MSVC_LIFETIMEBOUND) noexcept(noexcept(_Right < _Left)) /* strengthened */ {
// return pair(leftmost/smaller, rightmost/larger) of _Left and _Right
if (_Right < _Left) {
_STL_ASSERT(!(_Left < _Right), "invalid comparator");
Expand All @@ -10049,8 +10056,8 @@ namespace ranges {

template <class _Ty, class _Pj = identity,
indirect_strict_weak_order<projected<const _Ty*, _Pj>> _Pr = ranges::less>
_NODISCARD constexpr minmax_result<const _Ty&> operator()(
const _Ty& _Left, const _Ty& _Right, _Pr _Pred = {}, _Pj _Proj = {}) const {
_NODISCARD constexpr minmax_result<const _Ty&> operator()(const _Ty& _Left _MSVC_LIFETIMEBOUND,
const _Ty& _Right _MSVC_LIFETIMEBOUND, _Pr _Pred = {}, _Pj _Proj = {}) const {
if (_STD invoke(_Pred, _STD invoke(_Proj, _Right), _STD invoke(_Proj, _Left))) {
return {_Right, _Left};
} else {
Expand Down Expand Up @@ -10673,6 +10680,11 @@ namespace ranges {
#endif // _HAS_CXX17

_STD_END

// TRANSITION, non-_Ugly attribute tokens
#pragma pop_macro("lifetimebound")
#pragma pop_macro("msvc")

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
Expand Down
14 changes: 14 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,10 +663,12 @@
#pragma push_macro("known_semantics")
#pragma push_macro("noop_dtor")
#pragma push_macro("intrinsic")
#pragma push_macro("lifetimebound")
#undef msvc
#undef known_semantics
#undef noop_dtor
#undef intrinsic
#undef lifetimebound

#ifndef __has_cpp_attribute
#define _HAS_MSVC_ATTRIBUTE(x) 0
Expand Down Expand Up @@ -700,7 +702,19 @@
#define _MSVC_INTRINSIC
#endif

// Should we enable [[msvc::lifetimebound]] or [[clang::lifetimebound]] warnings?
#if !defined(__has_cpp_attribute) || defined(_SILENCE_LIFETIMEBOUND_WARNING)
#define _MSVC_LIFETIMEBOUND
#elif _HAS_MSVC_ATTRIBUTE(lifetimebound)
#define _MSVC_LIFETIMEBOUND [[msvc::lifetimebound]]
#elif __has_cpp_attribute(_Clang::__lifetimebound__)
Comment thread
StephanTLavavej marked this conversation as resolved.
#define _MSVC_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
#else
#define _MSVC_LIFETIMEBOUND
#endif

#undef _HAS_MSVC_ATTRIBUTE
#pragma pop_macro("lifetimebound")
#pragma pop_macro("intrinsic")
#pragma pop_macro("noop_dtor")
#pragma pop_macro("known_semantics")
Expand Down
2 changes: 2 additions & 0 deletions tests/std/lit.site.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ config.test_format = stl.test.format.STLTestFormat()
lit_config.expected_results = getattr(lit_config, 'expected_results', dict())
lit_config.include_dirs = getattr(lit_config, 'include_dirs', dict())
lit_config.library_dirs = getattr(lit_config, 'library_dirs', dict())
lit_config.ruleset_dirs = getattr(lit_config, 'ruleset_dirs', dict())
lit_config.test_subdirs = getattr(lit_config, 'test_subdirs', dict())

lit_config.expected_results[config.name] = stl.test.file_parsing.parse_result_file('@STD_EXPECTED_RESULTS@')
lit_config.include_dirs[config.name] = \
['@STL_TESTED_HEADERS_DIR@', '@LIBCXX_SOURCE_DIR@/test/support', '@STL_SOURCE_DIR@/tests/std/include']
lit_config.library_dirs[config.name] = ['@STL_LIBRARY_OUTPUT_DIRECTORY@', '@TOOLSET_LIB@']
lit_config.ruleset_dirs[config.name] = ['@STL_SOURCE_DIR@/tests/std/rulesets']
lit_config.test_subdirs[config.name] = ['@CMAKE_CURRENT_SOURCE_DIR@/tests']

lit_config.cxx_headers = '@STL_TESTED_HEADERS_DIR@'
Expand Down
11 changes: 11 additions & 0 deletions tests/std/rulesets/stl.ruleset
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. -->
<!-- SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -->
<RuleSet Name="STL Ruleset" Description="C++ Core Guidelines rules for microsoft/STL" ToolsVersion="15.0">
<Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
<!-- The pointer is dangling because it points at a temporary instance that was destroyed. (ES.65) -->
<Rule Id="C26815" Action="Warning" />
<!-- The pointer points to memory allocated on the stack (ES.65) -->
<Rule Id="C26816" Action="Warning" />
</Rules>
</RuleSet>
2 changes: 2 additions & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ tests\GH_002030_asan_annotate_vector
tests\GH_002039_byte_is_not_trivially_swappable
tests\GH_002045_put_time_changes_errno
tests\GH_002058_debug_iterator_race
# Needs special machinery to work in the MSVC-internal test harness, not yet implemented:
# tests\GH_002094_cpp_core_guidelines
tests\GH_002120_streambuf_seekpos_and_seekoff
tests\GH_002168_regex_overflow
tests\GH_002206_unreserved_names
Expand Down
16 changes: 16 additions & 0 deletions tests/std/tests/GH_002094_cpp_core_guidelines/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\prefix.lst
RUNALL_CROSSLIST
PM_CL="/EHsc /w14640 /Zc:threadSafeInit-"
RUNALL_CROSSLIST
PM_CL="/MD /D_ITERATOR_DEBUG_LEVEL=0 /std:c++14 /analyze:only /analyze:autolog- /analyze:plugin EspXEngine.dll /analyze:ruleset stl.ruleset"
PM_CL="/MDd /D_ITERATOR_DEBUG_LEVEL=2 /std:c++17 /permissive- /analyze:only /analyze:autolog- /analyze:plugin EspXEngine.dll /analyze:ruleset stl.ruleset"
PM_CL="/MDd /D_ITERATOR_DEBUG_LEVEL=2 /std:c++20 /permissive- /analyze:only /analyze:autolog- /analyze:plugin EspXEngine.dll /analyze:ruleset stl.ruleset"
PM_CL="/MT /D_ITERATOR_DEBUG_LEVEL=0 /std:c++latest /permissive- /analyze:only /analyze:autolog- /analyze:plugin EspXEngine.dll /analyze:ruleset stl.ruleset"
PM_CL="/MTd /D_ITERATOR_DEBUG_LEVEL=2 /std:c++latest /permissive- /analyze:only /analyze:autolog- /analyze:plugin EspXEngine.dll /analyze:ruleset stl.ruleset"
PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /MD /std:c++14"
PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /MDd /std:c++17"
PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /MT /std:c++20 /permissive-"
PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /MTd /std:c++latest /permissive-"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <__msvc_all_public_headers.hpp>
2 changes: 1 addition & 1 deletion tests/utils/stl/test/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class SharedState:
env: Dict[str, str] = field(default_factory=dict)

execDir, _ = test.getTempPaths()
shared = SharedState(None, execDir, copy.deepcopy(litConfig.test_env))
shared = SharedState(None, execDir, _mergeEnvironments(litConfig.test_env, test.env))
shared.env['TMP'] = execDir
shared.env['TEMP'] = execDir
shared.env['TMPDIR'] = execDir
Expand Down
14 changes: 14 additions & 0 deletions tests/utils/stl/test/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(self, suite, pathInSuite, litConfig, testConfig, envlstEntry, envNu
def configureTest(self, litConfig):
self.compileFlags = []
self.cxx = None
self.env = {}
self.fileDependencies = []
self.flags = []
self.isenseRspPath = None
Expand Down Expand Up @@ -234,7 +235,13 @@ def _addCustomFeature(self, name):
def _parseFlags(self, litConfig):
foundStd = False
foundCRT = False
afterAnalyzePlugin = False
for flag in chain(self.flags, self.compileFlags, self.linkFlags):
if afterAnalyzePlugin:
if 'EspXEngine.dll'.casefold() in flag.casefold():
self._addCustomFeature('espxengine')
afterAnalyzePlugin = False

if flag[1:5] == 'std:':
foundStd = True
if flag[5:] == 'c++latest':
Expand Down Expand Up @@ -279,6 +286,8 @@ def _parseFlags(self, litConfig):
self._addCustomFeature('MT')
self._addCustomFeature('static_CRT')
foundCRT = True
elif flag[1:] == 'analyze:plugin':
afterAnalyzePlugin = True

if not foundStd:
self._addCustomFeature('c++14')
Expand All @@ -294,6 +303,11 @@ def _parseFlags(self, litConfig):
if 'asan' in self.config.available_features and 'clang' in self.config.available_features:
self.linkFlags.append("/INFERASANLIBS")

# code analysis settings
if 'espxengine' in self.config.available_features:
self.compileFlags.extend(["/analyze:rulesetdirectory", ';'.join(litConfig.ruleset_dirs[self.config.name])])
self.env['Esp.Extensions'] = 'CppCoreCheck.dll'
self.env['Esp.AnnotationBuildLevel'] = 'Ignore'

class LibcxxTest(STLTest):
def getTestName(self):
Expand Down