Skip to content

Commit 8ac8190

Browse files
committed
v3.5.3
1 parent b20b365 commit 8ac8190

File tree

7 files changed

+259
-100
lines changed

7 files changed

+259
-100
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
3333
endif()
3434

3535
project(Catch2
36-
VERSION 3.5.2 # CML version placeholder, don't delete
36+
VERSION 3.5.3 # CML version placeholder, don't delete
3737
LANGUAGES CXX
3838
# HOMEPAGE_URL is not supported until CMake version 3.12, which
3939
# we do not target yet.

docs/release-notes.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Release notes
44
**Contents**<br>
5+
[3.5.3](#353)<br>
56
[3.5.2](#352)<br>
67
[3.5.1](#351)<br>
78
[3.5.0](#350)<br>
@@ -60,6 +61,31 @@
6061
[Even Older versions](#even-older-versions)<br>
6162

6263

64+
## 3.5.3
65+
66+
### Fixes
67+
* Fixed OOB access when computing filename tag (from the `-#` flag) for file without extension (#2798)
68+
* Fixed the linking against `log` on Android to be `PRIVATE` (#2815)
69+
* Fixed `Wuseless-cast` in benchmarking internals (#2823)
70+
71+
### Improvements
72+
* Restored compatibility with VS2017 (#2792, #2822)
73+
* The baseline for Catch2 is still C++14 with some reasonable workarounds for specific compilers, so if VS2017 starts acting up again, the support will be dropped again.
74+
* Suppressed clang-tidy's `bugprone-chained-comparison` in assertions (#2801)
75+
* Improved the static analysis mode to evaluate arguments to `TEST_CASE` and `SECTION` (#2817)
76+
* Clang-tidy should no longer warn about runtime arguments to these macros being unused in static analysis mode.
77+
* Clang-tidy can warn on issues involved arguments to these macros.
78+
* Added support for literal-zero detectors based on `consteval` constructors
79+
* This is required for compiling `REQUIRE((a <=> b) == 0)` against MSVC's stdlib.
80+
* Sadly, MSVC still cannot compile this assertion as it does not implement C++20 correctly.
81+
* You can use `clang-cl` with MSVC's stdlib instead.
82+
* If for some godforsaken reasons you want to understand this better, read the two relevant commits: [`dc51386b9fd61f99ea9c660d01867e6ad489b403`](https://github.com/catchorg/Catch2/commit/dc51386b9fd61f99ea9c660d01867e6ad489b403), and [`0787132fc82a75e3fb255aa9484ca1dc1eff2a30`](https://github.com/catchorg/Catch2/commit/0787132fc82a75e3fb255aa9484ca1dc1eff2a30).
83+
84+
### Miscellaneous
85+
* Disabled tests for FP random generator reproducibility on non-SSE2 x86 targets (#2796)
86+
* Modified the in-tree Conan recipe to support Conan 2 (#2805)
87+
88+
6389
## 3.5.2
6490

6591
### Fixes

extras/catch_amalgamated.cpp

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
// SPDX-License-Identifier: BSL-1.0
88

9-
// Catch v3.5.2
10-
// Generated: 2024-01-15 14:06:36.675713
9+
// Catch v3.5.3
10+
// Generated: 2024-03-01 22:05:56.038084
1111
// ----------------------------------------------------------
1212
// This file is an amalgamation of multiple different files.
1313
// You probably shouldn't edit it directly.
@@ -101,8 +101,8 @@ namespace Catch {
101101
FDuration mean = FDuration(0);
102102
int i = 0;
103103
for (auto it = first; it < last; ++it, ++i) {
104-
samples.push_back(FDuration(*it));
105-
mean += FDuration(*it);
104+
samples.push_back(*it);
105+
mean += *it;
106106
}
107107
mean /= i;
108108

@@ -558,7 +558,7 @@ bool marginComparison(double lhs, double rhs, double margin) {
558558
namespace Catch {
559559

560560
Approx::Approx ( double value )
561-
: m_epsilon( std::numeric_limits<float>::epsilon()*100. ),
561+
: m_epsilon( static_cast<double>(std::numeric_limits<float>::epsilon())*100. ),
562562
m_margin( 0.0 ),
563563
m_scale( 0.0 ),
564564
m_value( value )
@@ -1038,6 +1038,7 @@ namespace Catch {
10381038
m_messages.back().message += " := ";
10391039
start = pos;
10401040
}
1041+
default:; // noop
10411042
}
10421043
}
10431044
assert(openings.empty() && "Mismatched openings");
@@ -1581,8 +1582,10 @@ namespace Catch {
15811582
while (lastDot > 0 && filename[lastDot - 1] != '.') {
15821583
--lastDot;
15831584
}
1584-
--lastDot;
1585+
// In theory we could have filename without any extension in it
1586+
if ( lastDot == 0 ) { return StringRef(); }
15851587

1588+
--lastDot;
15861589
size_t nameStart = lastDot;
15871590
while (nameStart > 0 && filename[nameStart - 1] != '/' && filename[nameStart - 1] != '\\') {
15881591
--nameStart;
@@ -1966,13 +1969,13 @@ namespace Detail {
19661969
}
19671970
} // end unnamed namespace
19681971

1969-
std::string convertIntoString(StringRef string, bool escape_invisibles) {
1972+
std::string convertIntoString(StringRef string, bool escapeInvisibles) {
19701973
std::string ret;
19711974
// This is enough for the "don't escape invisibles" case, and a good
19721975
// lower bound on the "escape invisibles" case.
19731976
ret.reserve(string.size() + 2);
19741977

1975-
if (!escape_invisibles) {
1978+
if (!escapeInvisibles) {
19761979
ret += '"';
19771980
ret += string;
19781981
ret += '"';
@@ -2050,7 +2053,7 @@ std::string StringMaker<char const*>::convert(char const* str) {
20502053
return{ "{null string}" };
20512054
}
20522055
}
2053-
std::string StringMaker<char*>::convert(char* str) {
2056+
std::string StringMaker<char*>::convert(char* str) { // NOLINT(readability-non-const-parameter)
20542057
if (str) {
20552058
return Detail::convertIntoString( str );
20562059
} else {
@@ -2147,8 +2150,8 @@ std::string StringMaker<signed char>::convert(signed char value) {
21472150
std::string StringMaker<char>::convert(char c) {
21482151
return ::Catch::Detail::stringify(static_cast<signed char>(c));
21492152
}
2150-
std::string StringMaker<unsigned char>::convert(unsigned char c) {
2151-
return ::Catch::Detail::stringify(static_cast<char>(c));
2153+
std::string StringMaker<unsigned char>::convert(unsigned char value) {
2154+
return ::Catch::Detail::stringify(static_cast<char>(value));
21522155
}
21532156

21542157
int StringMaker<float>::precision = 5;
@@ -2268,7 +2271,7 @@ namespace Catch {
22682271
}
22692272

22702273
Version const& libraryVersion() {
2271-
static Version version( 3, 5, 2, "", 0 );
2274+
static Version version( 3, 5, 3, "", 0 );
22722275
return version;
22732276
}
22742277

@@ -3092,7 +3095,7 @@ namespace Catch {
30923095
line = trim(line);
30933096
if( !line.empty() && !startsWith( line, '#' ) ) {
30943097
if( !startsWith( line, '"' ) )
3095-
line = '"' + line + '"';
3098+
line = '"' + CATCH_MOVE(line) + '"';
30963099
config.testsOrTags.push_back( line );
30973100
config.testsOrTags.emplace_back( "," );
30983101
}
@@ -3573,21 +3576,21 @@ namespace {
35733576

35743577
namespace Catch {
35753578

3576-
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode implSelection,
3579+
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
35773580
IStream* stream ) {
35783581
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
3579-
if ( implSelection == ColourMode::Win32 ) {
3582+
if ( colourSelection == ColourMode::Win32 ) {
35803583
return Detail::make_unique<Win32ColourImpl>( stream );
35813584
}
35823585
#endif
3583-
if ( implSelection == ColourMode::ANSI ) {
3586+
if ( colourSelection == ColourMode::ANSI ) {
35843587
return Detail::make_unique<ANSIColourImpl>( stream );
35853588
}
3586-
if ( implSelection == ColourMode::None ) {
3589+
if ( colourSelection == ColourMode::None ) {
35873590
return Detail::make_unique<NoColourImpl>( stream );
35883591
}
35893592

3590-
if ( implSelection == ColourMode::PlatformDefault) {
3593+
if ( colourSelection == ColourMode::PlatformDefault) {
35913594
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
35923595
if ( Win32ColourImpl::useImplementationForStream( *stream ) ) {
35933596
return Detail::make_unique<Win32ColourImpl>( stream );
@@ -3599,7 +3602,7 @@ namespace Catch {
35993602
return Detail::make_unique<NoColourImpl>( stream );
36003603
}
36013604

3602-
CATCH_ERROR( "Could not create colour impl for selection " << static_cast<int>(implSelection) );
3605+
CATCH_ERROR( "Could not create colour impl for selection " << static_cast<int>(colourSelection) );
36033606
}
36043607

36053608
bool isColourImplAvailable( ColourMode colourSelection ) {
@@ -3807,7 +3810,12 @@ namespace Catch {
38073810

38083811
namespace Catch {
38093812

3810-
ITransientExpression::~ITransientExpression() = default;
3813+
void ITransientExpression::streamReconstructedExpression(
3814+
std::ostream& os ) const {
3815+
// We can't make this function pure virtual to keep ITransientExpression
3816+
// constexpr, so we write error message instead
3817+
os << "Some class derived from ITransientExpression without overriding streamReconstructedExpression";
3818+
}
38113819

38123820
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
38133821
if( lhs.size() + rhs.size() < 40 &&
@@ -4473,7 +4481,7 @@ namespace Catch {
44734481
m_os{ os }, m_indent_level{ indent_level } {
44744482
m_os << '{';
44754483
}
4476-
JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ):
4484+
JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ) noexcept:
44774485
m_os{ source.m_os },
44784486
m_indent_level{ source.m_indent_level },
44794487
m_should_comma{ source.m_should_comma },
@@ -4504,7 +4512,7 @@ namespace Catch {
45044512
m_os{ os }, m_indent_level{ indent_level } {
45054513
m_os << '[';
45064514
}
4507-
JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ):
4515+
JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ) noexcept:
45084516
m_os{ source.m_os },
45094517
m_indent_level{ source.m_indent_level },
45104518
m_should_comma{ source.m_should_comma },
@@ -5283,7 +5291,7 @@ namespace Catch {
52835291
auto kv = splitKVPair( parts[i] );
52845292
auto key = kv.key, value = kv.value;
52855293

5286-
if ( key.empty() || value.empty() ) {
5294+
if ( key.empty() || value.empty() ) { // NOLINT(bugprone-branch-clone)
52875295
return {};
52885296
} else if ( key[0] == 'X' ) {
52895297
// This is a reporter-specific option, we don't check these
@@ -6297,17 +6305,29 @@ namespace Catch {
62976305
}
62986306

62996307
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
6300-
bool replaced = false;
63016308
std::size_t i = str.find( replaceThis );
6302-
while( i != std::string::npos ) {
6303-
replaced = true;
6304-
str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
6305-
if( i < str.size()-withThis.size() )
6306-
i = str.find( replaceThis, i+withThis.size() );
6309+
if (i == std::string::npos) {
6310+
return false;
6311+
}
6312+
std::size_t copyBegin = 0;
6313+
std::string origStr = CATCH_MOVE(str);
6314+
str.clear();
6315+
// There is at least one replacement, so reserve with the best guess
6316+
// we can make without actually counting the number of occurences.
6317+
str.reserve(origStr.size() - replaceThis.size() + withThis.size());
6318+
do {
6319+
str.append(origStr, copyBegin, i-copyBegin );
6320+
str += withThis;
6321+
copyBegin = i + replaceThis.size();
6322+
if( copyBegin < origStr.size() )
6323+
i = origStr.find( replaceThis, copyBegin );
63076324
else
63086325
i = std::string::npos;
6326+
} while( i != std::string::npos );
6327+
if ( copyBegin < origStr.size() ) {
6328+
str.append(origStr, copyBegin, origStr.size() );
63096329
}
6310-
return replaced;
6330+
return true;
63116331
}
63126332

63136333
std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
@@ -9099,8 +9119,8 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
90999119
m_stream << '\n' << std::flush;
91009120
StreamingReporterBase::testRunEnded(_testRunStats);
91019121
}
9102-
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
9103-
StreamingReporterBase::testRunStarting(_testInfo);
9122+
void ConsoleReporter::testRunStarting(TestRunInfo const& _testRunInfo) {
9123+
StreamingReporterBase::testRunStarting(_testRunInfo);
91049124
if ( m_config->testSpec().hasFilters() ) {
91059125
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
91069126
<< m_config->testSpec() << '\n';
@@ -9253,8 +9273,7 @@ namespace Catch {
92539273
namespace {
92549274
struct BySectionInfo {
92559275
BySectionInfo( SectionInfo const& other ): m_other( other ) {}
9256-
BySectionInfo( BySectionInfo const& other ):
9257-
m_other( other.m_other ) {}
9276+
BySectionInfo( BySectionInfo const& other ) = default;
92589277
bool operator()(
92599278
Detail::unique_ptr<CumulativeReporterBase::SectionNode> const&
92609279
node ) const {
@@ -9879,8 +9898,8 @@ namespace Catch {
98799898
return "Outputs listings as JSON. Test listing is Work-in-Progress!";
98809899
}
98819900

9882-
void JsonReporter::testRunStarting( TestRunInfo const& testInfo ) {
9883-
StreamingReporterBase::testRunStarting( testInfo );
9901+
void JsonReporter::testRunStarting( TestRunInfo const& runInfo ) {
9902+
StreamingReporterBase::testRunStarting( runInfo );
98849903
endListing();
98859904

98869905
assert( isInside( Writer::Object ) );
@@ -10178,7 +10197,7 @@ namespace Catch {
1017810197

1017910198
static void normalizeNamespaceMarkers(std::string& str) {
1018010199
std::size_t pos = str.find( "::" );
10181-
while ( pos != str.npos ) {
10200+
while ( pos != std::string::npos ) {
1018210201
str.replace( pos, 2, "." );
1018310202
pos += 1;
1018410203
pos = str.find( "::", pos );

0 commit comments

Comments
 (0)