From f782ce1691e2bd41d2d259099749530719dc7fd2 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 12:31:02 -0400 Subject: [PATCH 01/16] Runtime coverage for optional::operator-> Coverage was constexpr only. Improve report. --- Makefile | 6 +++++- tests/beman/optional/optional_ref.t.cpp | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 73edb673..f27b162a 100755 --- a/Makefile +++ b/Makefile @@ -167,11 +167,15 @@ lint-manual: ## Run all manual tools in pre-commit .PHONY: coverage coverage: ## Build and run the tests with the GCOV profile and process the results -coverage: venv +coverage: venv $(_build_path)/CMakeCache.txt $(ACTIVATE) cmake --build $(_build_path) --config Gcov $(ACTIVATE) ctest --build-config Gcov --output-on-failure --test-dir $(_build_path) $(ACTIVATE) cmake --build $(_build_path) --config Gcov --target process_coverage +.PHONY: view-coverage +view-coverage: ## View the coverage report + sensible-browser $(_build_path)/coverage/coverage.html + # Help target .PHONY: help help: ## Show this help. diff --git a/tests/beman/optional/optional_ref.t.cpp b/tests/beman/optional/optional_ref.t.cpp index 0bc9deae..c25276ac 100644 --- a/tests/beman/optional/optional_ref.t.cpp +++ b/tests/beman/optional/optional_ref.t.cpp @@ -527,17 +527,21 @@ TEST(OptionalRefTest, Observers) { beman::optional::optional ob1 = i1; beman::optional::optional ob2; const beman::optional::optional ob3 = i1; - success = std::is_samei_), int>::value; - static_assert(std::is_samei_), int>::value); + + EXPECT_EQ(ob1->i_, 3); + EXPECT_EQ(ob3->i_, 3); + + success = std::is_same_vi_), int>; + static_assert(std::is_same_vi_), int>); EXPECT_TRUE(success); - success = std::is_samei_), int>::value; - static_assert(std::is_samei_), int>::value); + success = std::is_same_vi_), int>; + static_assert(std::is_same_vi_), int>); EXPECT_TRUE(success); - success = std::is_samei_), int>::value; - static_assert(std::is_samei_), int>::value); + success = std::is_same_vi_), int>; + static_assert(std::is_same_vi_), int>); EXPECT_TRUE(success); - success = std::is_samei_), int>::value; - static_assert(std::is_samei_), int>::value); + success = std::is_same_vi_), int>; + static_assert(std::is_same_vi_), int>); EXPECT_TRUE(success); } From 3e39004f37dc8f8333307f04ea06069f3118460a Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 12:48:12 -0400 Subject: [PATCH 02/16] Nullopt assignment for coverage --- tests/beman/optional/optional_ref.t.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/beman/optional/optional_ref.t.cpp b/tests/beman/optional/optional_ref.t.cpp index c25276ac..cf59921b 100644 --- a/tests/beman/optional/optional_ref.t.cpp +++ b/tests/beman/optional/optional_ref.t.cpp @@ -152,6 +152,19 @@ TEST(OptionalRefTest, Assignment) { EXPECT_EQ(*o2, 7); } +TEST(OptionalRefTest, NullOptAssignment) { + beman::optional::optional i1; + EXPECT_FALSE(i1); + int i = 5; + i1 = i; + + EXPECT_TRUE(i1); + i1 = beman::optional::nullopt; + EXPECT_FALSE(i1); + i1 = beman::optional::optional{i}; + EXPECT_TRUE(i1); +} + TEST(OptionalRefTest, RelationalOps) { int i1 = 4; int i2 = 42; From 24acb0aefc82dae5a7b3465a7d27e4821ad469db Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 13:05:36 -0400 Subject: [PATCH 03/16] Even less inline for coverage Delegating constructor still becomes inlined, unfortunately. --- etc/gcc-flags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/gcc-flags.cmake b/etc/gcc-flags.cmake index 1d451f59..a66ebc89 100644 --- a/etc/gcc-flags.cmake +++ b/etc/gcc-flags.cmake @@ -36,7 +36,7 @@ set(CMAKE_CXX_FLAGS_ASAN ) set(CMAKE_CXX_FLAGS_GCOV - "-O0 -fno-inline -g --coverage -fprofile-abs-path" + "-O0 -fno-default-inline -fno-inline -fkeep-inline-functions -g --coverage -fprofile-abs-path" CACHE STRING "C++ GCOV Flags" FORCE From 1aa1442f8fbd4b5a7f226529a509d0333e0321a3 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 13:06:37 -0400 Subject: [PATCH 04/16] Explicit nollopt construction Delegating constructor gets inlined so coverage is still wrong. --- tests/beman/optional/optional_ref.t.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/beman/optional/optional_ref.t.cpp b/tests/beman/optional/optional_ref.t.cpp index cf59921b..0bd8d8a3 100644 --- a/tests/beman/optional/optional_ref.t.cpp +++ b/tests/beman/optional/optional_ref.t.cpp @@ -162,6 +162,16 @@ TEST(OptionalRefTest, NullOptAssignment) { i1 = beman::optional::nullopt; EXPECT_FALSE(i1); i1 = beman::optional::optional{i}; +TEST(OptionalRefTest, NullOptConstruction) { + beman::optional::optional i1(beman::optional::nullopt); + EXPECT_FALSE(i1); + int i = 5; + i1 = i; + + EXPECT_TRUE(i1); + i1 = beman::optional::nullopt; + EXPECT_FALSE(i1); + i1 = i; EXPECT_TRUE(i1); } From c3fde21863ff7cd14b28c3173f5b201a428150b7 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 13:07:28 -0400 Subject: [PATCH 05/16] Branch coverage for converting constructor Cover the empty branch --- tests/beman/optional/optional_ref.t.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/beman/optional/optional_ref.t.cpp b/tests/beman/optional/optional_ref.t.cpp index 0bd8d8a3..ec197a5f 100644 --- a/tests/beman/optional/optional_ref.t.cpp +++ b/tests/beman/optional/optional_ref.t.cpp @@ -92,6 +92,8 @@ beman::optional::optional process() { return t; } +beman::optional::optional processEmpty() { return beman::optional::nullopt; } + TEST(OptionalRefTest, BaseDerivedCastConstruction) { base b; derived& dref(b); // ok @@ -145,6 +147,9 @@ TEST(OptionalRefTest, Assignment) { o = process(); // well-formed EXPECT_TRUE(o); + o = processEmpty(); // well-formed + EXPECT_FALSE(o); + beman::optional::optional o2; EXPECT_FALSE(o2); o2 = [&]() { return i1; }(); @@ -161,7 +166,10 @@ TEST(OptionalRefTest, NullOptAssignment) { EXPECT_TRUE(i1); i1 = beman::optional::nullopt; EXPECT_FALSE(i1); - i1 = beman::optional::optional{i}; + i1 = i; + EXPECT_TRUE(i1); +} + TEST(OptionalRefTest, NullOptConstruction) { beman::optional::optional i1(beman::optional::nullopt); EXPECT_FALSE(i1); From b4e65dff004c8ddbd52f4399d51145fcd89599c8 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 13:17:44 -0400 Subject: [PATCH 06/16] Add const ref assignment test for coverage --- tests/beman/optional/optional_ref.t.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/beman/optional/optional_ref.t.cpp b/tests/beman/optional/optional_ref.t.cpp index ec197a5f..6af098b2 100644 --- a/tests/beman/optional/optional_ref.t.cpp +++ b/tests/beman/optional/optional_ref.t.cpp @@ -170,6 +170,23 @@ TEST(OptionalRefTest, NullOptAssignment) { EXPECT_TRUE(i1); } +TEST(OptionalRefTest, ConstRefAssignment) { + int i = 7; + beman::optional::optional i1{i}; + const beman::optional::optional i2 = i1; + + beman::optional::optional c1; + c1 = i2; + EXPECT_TRUE(c1); + EXPECT_EQ(*c1, 7); + + i = 5; + EXPECT_EQ(*c1, 5); + const beman::optional::optional empty(beman::optional::nullopt); + c1 = empty; + EXPECT_FALSE(c1); +} + TEST(OptionalRefTest, NullOptConstruction) { beman::optional::optional i1(beman::optional::nullopt); EXPECT_FALSE(i1); From 9aab97ad23dee82949d5f53ca7fd953af99f6a0c Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 13:22:11 -0400 Subject: [PATCH 07/16] Add ConvertingConstRvalRef for coverage --- tests/beman/optional/optional_ref.t.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/beman/optional/optional_ref.t.cpp b/tests/beman/optional/optional_ref.t.cpp index 6af098b2..321c0356 100644 --- a/tests/beman/optional/optional_ref.t.cpp +++ b/tests/beman/optional/optional_ref.t.cpp @@ -187,6 +187,23 @@ TEST(OptionalRefTest, ConstRefAssignment) { EXPECT_FALSE(c1); } +TEST(OptionalRefTest, ConvertingConstRvalRef) { + int i = 7; + beman::optional::optional i1{i}; + const beman::optional::optional i2 = i1; + + beman::optional::optional c1; + c1 = std::move(i2); + EXPECT_TRUE(c1); + EXPECT_EQ(*c1, 7); + + i = 5; + EXPECT_EQ(*c1, 5); + const beman::optional::optional empty(beman::optional::nullopt); + c1 = std::move(empty); + EXPECT_FALSE(c1); +} + TEST(OptionalRefTest, NullOptConstruction) { beman::optional::optional i1(beman::optional::nullopt); EXPECT_FALSE(i1); From b25de95415c679c33929bc4b09c50a30a0ace357 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 14:06:04 -0400 Subject: [PATCH 08/16] Test and cover emplace variadic and intializer list --- tests/beman/optional/optional.t.cpp | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/beman/optional/optional.t.cpp b/tests/beman/optional/optional.t.cpp index ae2296a8..f094e40c 100644 --- a/tests/beman/optional/optional.t.cpp +++ b/tests/beman/optional/optional.t.cpp @@ -153,6 +153,52 @@ TEST(OptionalTest, OptionalOfOptional) { EXPECT_TRUE(oo2.value() == 43); } +TEST(OptionalTest, EmplaceVariadic) { + struct for_emplace { + int a; + int b; + int c; + } f{4, 5, 6}; + + beman::optional::optional o3; + o3.emplace(1, 2, 3); + EXPECT_TRUE(o3.has_value()); + + beman::optional::optional engaged{f}; + engaged.emplace(1, 2, 3); + EXPECT_TRUE(engaged.has_value()); + EXPECT_EQ(engaged->a, 1); +} + +TEST(OptionalTest, EmplaceInitializerList) { + struct for_emplace { + std::vector v; //something to construct with list + std::string name = ""; + for_emplace(std::initializer_list l) : v(l){ + } + for_emplace(std::initializer_list l, std::string n) : v(l), name(n) {} + } f{{1,2,3}}; + + beman::optional::optional o3; + o3.emplace({1, 2, 3}); + EXPECT_TRUE(o3.has_value()); + + beman::optional::optional engaged{f}; + auto e1 = engaged.emplace({1, 2, 3}); + EXPECT_TRUE(engaged.has_value()); + EXPECT_EQ(engaged->v[0], 1); + EXPECT_EQ(engaged->name, std::string("")); + EXPECT_EQ(engaged->v[0], e1.v[0]); + EXPECT_EQ(engaged->name, e1.name); + + auto e2 = engaged.emplace({2, 3, 4}, "Name"); + EXPECT_TRUE(engaged.has_value()); + EXPECT_EQ(engaged->v[0], 2); + EXPECT_EQ(engaged->name, std::string("Name")); + EXPECT_EQ(engaged->v[0], e2.v[0]); + EXPECT_EQ(engaged->name, e2.name); +} + TEST(OptionalTest, AssignmentValue) { beman::optional::optional o1 = 42; beman::optional::optional o2 = 12; @@ -243,6 +289,31 @@ TEST(OptionalTest, AssignmentValue) { EXPECT_FALSE(o8); } +TEST(OptionalTest, ValueObserver) { + beman::optional::optional empty; + beman::optional::optional bound{5}; + EXPECT_TRUE(bound); + EXPECT_FALSE(empty); + EXPECT_EQ(*bound, 5); + EXPECT_EQ(bound.value(), 5); + EXPECT_EQ(std::as_const(bound).value(), 5); + EXPECT_EQ(std::move(bound).value(), 5); + + EXPECT_THROW( + { + try { + empty.value(); + } catch (const beman::optional::bad_optional_access& e) { + EXPECT_STREQ("Optional has no value", e.what()); + throw; + } + }, + beman::optional::bad_optional_access); + + EXPECT_THROW({ std::as_const(empty).value(); }, beman::optional::bad_optional_access); + EXPECT_THROW({ std::move(empty).value(); }, beman::optional::bad_optional_access); +} + TEST(OptionalTest, Triviality) { EXPECT_TRUE(std::is_trivially_copy_constructible>::value); EXPECT_TRUE(std::is_trivially_copy_assignable>::value); From e70d753a463958707e35b907f612713cdf054e9c Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 14:14:11 -0400 Subject: [PATCH 09/16] Test hard_reset branch for operator=(const optional& rhs) Coverage testing operator=(const optional& rhs) --- tests/beman/optional/optional.t.cpp | 4 ++++ tests/beman/optional/optional_constexpr.t.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/beman/optional/optional.t.cpp b/tests/beman/optional/optional.t.cpp index f094e40c..7280a4c4 100644 --- a/tests/beman/optional/optional.t.cpp +++ b/tests/beman/optional/optional.t.cpp @@ -238,6 +238,10 @@ TEST(OptionalTest, AssignmentValue) { o1 = s; EXPECT_TRUE(*o1 == 54); + beman::optional::optional emptyShort; + o1 = emptyShort; + EXPECT_FALSE(o1); + struct not_trivial_copy_assignable { int i_; constexpr not_trivial_copy_assignable(int i) : i_(i) {} diff --git a/tests/beman/optional/optional_constexpr.t.cpp b/tests/beman/optional/optional_constexpr.t.cpp index 00b64aab..58e2c7bb 100644 --- a/tests/beman/optional/optional_constexpr.t.cpp +++ b/tests/beman/optional/optional_constexpr.t.cpp @@ -161,6 +161,10 @@ consteval bool testConstexprAssignmentValue() { o1 = s; retval &= (*o1 == 54); + beman::optional::optional emptyShort; + o1 = emptyShort; + retval &= !o1.has_value(); + struct not_trivial_copy_assignable { int i_; constexpr not_trivial_copy_assignable(int i) : i_(i) {} From fa0a0cd508def67e069a44da0b09c134a5673130 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 14:59:25 -0400 Subject: [PATCH 10/16] Formatting for emplace test --- tests/beman/optional/optional.t.cpp | 43 +++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/tests/beman/optional/optional.t.cpp b/tests/beman/optional/optional.t.cpp index 7280a4c4..dcfe646e 100644 --- a/tests/beman/optional/optional.t.cpp +++ b/tests/beman/optional/optional.t.cpp @@ -172,19 +172,20 @@ TEST(OptionalTest, EmplaceVariadic) { TEST(OptionalTest, EmplaceInitializerList) { struct for_emplace { - std::vector v; //something to construct with list - std::string name = ""; - for_emplace(std::initializer_list l) : v(l){ - } + std::vector v; // something to construct with list + std::string name = ""; + for_emplace(std::initializer_list l) : v(l) {} for_emplace(std::initializer_list l, std::string n) : v(l), name(n) {} - } f{{1,2,3}}; + } f{{1, 2, 3}}; beman::optional::optional o3; o3.emplace({1, 2, 3}); EXPECT_TRUE(o3.has_value()); beman::optional::optional engaged{f}; + auto e1 = engaged.emplace({1, 2, 3}); + EXPECT_TRUE(engaged.has_value()); EXPECT_EQ(engaged->v[0], 1); EXPECT_EQ(engaged->name, std::string("")); @@ -242,6 +243,11 @@ TEST(OptionalTest, AssignmentValue) { o1 = emptyShort; EXPECT_FALSE(o1); + o1 = o4; + EXPECT_TRUE(*o1 == 42); + o1 = std::move(emptyShort); + EXPECT_FALSE(o1); + struct not_trivial_copy_assignable { int i_; constexpr not_trivial_copy_assignable(int i) : i_(i) {} @@ -293,6 +299,33 @@ TEST(OptionalTest, AssignmentValue) { EXPECT_FALSE(o8); } +TEST(OptionalTest, ConvertingAssignmentValue) { + beman::optional::optional o1 = 42; + beman::optional::optional o2; + + short s = 9; + o1 = s; + o2 = s; + EXPECT_TRUE(o1); + EXPECT_TRUE(o2); +} + +TEST(OptionalTest, ConvertingValueAssignment) { + struct base {}; + + struct convertable { + operator base() { return base{}; } + }; + + beman::optional::optional empty; + beman::optional::optional engaged(base{}); + + empty = convertable{}; + engaged = convertable{}; + EXPECT_TRUE(empty); + EXPECT_TRUE(engaged); +} + TEST(OptionalTest, ValueObserver) { beman::optional::optional empty; beman::optional::optional bound{5}; From 8e0699e1a3e70f3d396a5088a4d3dc9dd8c5114f Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 14:59:51 -0400 Subject: [PATCH 11/16] Test constexpr move converting assignment --- tests/beman/optional/optional_constexpr.t.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/beman/optional/optional_constexpr.t.cpp b/tests/beman/optional/optional_constexpr.t.cpp index 58e2c7bb..626ce9e2 100644 --- a/tests/beman/optional/optional_constexpr.t.cpp +++ b/tests/beman/optional/optional_constexpr.t.cpp @@ -165,6 +165,10 @@ consteval bool testConstexprAssignmentValue() { o1 = emptyShort; retval &= !o1.has_value(); + o1 = o4; + o1 = std::move(emptyShort); + retval &= !o1.has_value(); + struct not_trivial_copy_assignable { int i_; constexpr not_trivial_copy_assignable(int i) : i_(i) {} From 96f68b1edcc3c94a39ab1d0d00a3a7815400c3d2 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 15:15:59 -0400 Subject: [PATCH 12/16] Test variadic make_optional Coverage says not covered. --- tests/beman/optional/optional.t.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/beman/optional/optional.t.cpp b/tests/beman/optional/optional.t.cpp index dcfe646e..9849cba2 100644 --- a/tests/beman/optional/optional.t.cpp +++ b/tests/beman/optional/optional.t.cpp @@ -509,6 +509,16 @@ TEST(OptionalTest, MakeOptional) { EXPECT_TRUE(o5->v[1] == 1); EXPECT_TRUE(std::get<0>(o5->t) == 2); EXPECT_TRUE(std::get<1>(o5->t) == 3); + + struct for_variadic { + int a; + int b; + int c; + }; + + auto o6 = beman::optional::make_optional(0, 1, 3); + EXPECT_TRUE(o6); + EXPECT_EQ(o6->a, 0); } TEST(OptionalTest, Nullopt) { From 272cbf146fce1e56a9febb06649bb7695367f8df Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 15:32:56 -0400 Subject: [PATCH 13/16] Add llvm coverage tool --- etc/clang-20-toolchain.cmake | 1 + etc/clang-21-toolchain.cmake | 1 + 2 files changed, 2 insertions(+) diff --git a/etc/clang-20-toolchain.cmake b/etc/clang-20-toolchain.cmake index b41013da..d2be17fa 100644 --- a/etc/clang-20-toolchain.cmake +++ b/etc/clang-20-toolchain.cmake @@ -7,5 +7,6 @@ include_guard(GLOBAL) set(CMAKE_C_COMPILER clang-20) set(CMAKE_CXX_COMPILER clang++-20) +set(GCOV_EXECUTABLE "llvm-cov-20 gcov" CACHE STRING "GCOV executable" FORCE) include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") diff --git a/etc/clang-21-toolchain.cmake b/etc/clang-21-toolchain.cmake index a2c0b6d7..1f533a40 100644 --- a/etc/clang-21-toolchain.cmake +++ b/etc/clang-21-toolchain.cmake @@ -7,5 +7,6 @@ include_guard(GLOBAL) set(CMAKE_C_COMPILER clang-21) set(CMAKE_CXX_COMPILER clang++-21) +set(GCOV_EXECUTABLE "llvm-cov-21 gcov" CACHE STRING "GCOV executable" FORCE) include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") From bd5823390ad2075d0d044fb001c5329876c60666 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 15:36:05 -0400 Subject: [PATCH 14/16] Fix spelling : convertible not able. Code spell lint fix --- tests/beman/optional/optional.t.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/beman/optional/optional.t.cpp b/tests/beman/optional/optional.t.cpp index 9849cba2..c76bb6f6 100644 --- a/tests/beman/optional/optional.t.cpp +++ b/tests/beman/optional/optional.t.cpp @@ -313,15 +313,15 @@ TEST(OptionalTest, ConvertingAssignmentValue) { TEST(OptionalTest, ConvertingValueAssignment) { struct base {}; - struct convertable { + struct convertible { operator base() { return base{}; } }; beman::optional::optional empty; beman::optional::optional engaged(base{}); - empty = convertable{}; - engaged = convertable{}; + empty = convertible{}; + engaged = convertible{}; EXPECT_TRUE(empty); EXPECT_TRUE(engaged); } From 2f1c02606c10f61ddc298a1a0200185c159bd652 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 15:54:09 -0400 Subject: [PATCH 15/16] Ubuntu 24.04, gcc14, and inline disagree with each other ```txt /usr/bin/ld: lib/Gcov/libgtest.a(gtest-all.cc.o): in function `std::nextafter(_Float16, _Float16)': /usr/include/c++/14/cmath:2877:(.text._ZSt9nextafterDF16_DF16_[_ZSt9nextafterDF16_DF16_]+0x6a): undefined reference to `nextafterf16' /usr/bin/ld: lib/Gcov/libgtest.a(gtest-all.cc.o): in function `std::nextafter(std::bfloat16_t, std::bfloat16_t)': /usr/include/c++/14/cmath:3595:(.text._ZSt9nextafterDF16bDF16b[_ZSt9nextafterDF16bDF16b]+0x6a): undefined reference to `__builtin_nextafterf16b' ``` Bug reports suggest libc vs libstdc++ issues around optimization and inlining. Allowing more inlining in gcov profile. --- etc/gcc-flags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/gcc-flags.cmake b/etc/gcc-flags.cmake index a66ebc89..ee542b2b 100644 --- a/etc/gcc-flags.cmake +++ b/etc/gcc-flags.cmake @@ -36,7 +36,7 @@ set(CMAKE_CXX_FLAGS_ASAN ) set(CMAKE_CXX_FLAGS_GCOV - "-O0 -fno-default-inline -fno-inline -fkeep-inline-functions -g --coverage -fprofile-abs-path" + "-O0 -fno-inline -fkeep-inline-functions -g --coverage -fprofile-abs-path" CACHE STRING "C++ GCOV Flags" FORCE From 2be4c23cf629261b30b811c6950b1788deb3f3d1 Mon Sep 17 00:00:00 2001 From: Steve Downey Date: Mon, 26 May 2025 16:02:01 -0400 Subject: [PATCH 16/16] Remove keep inline functions for coverage -fkeep-inline-functions seems to involved with failures on Ubuntu 24.04 and GCC14 with an inline definition unavailable at link time. This is causing CI errors. --- etc/gcc-flags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/gcc-flags.cmake b/etc/gcc-flags.cmake index ee542b2b..641808d1 100644 --- a/etc/gcc-flags.cmake +++ b/etc/gcc-flags.cmake @@ -36,7 +36,7 @@ set(CMAKE_CXX_FLAGS_ASAN ) set(CMAKE_CXX_FLAGS_GCOV - "-O0 -fno-inline -fkeep-inline-functions -g --coverage -fprofile-abs-path" + "-O0 -fno-default-inline -fno-inline -g --coverage -fprofile-abs-path" CACHE STRING "C++ GCOV Flags" FORCE