ned14 / outcome

Provides very lightweight outcome<T> and result<T> (non-Boost edition)
https://ned14.github.io/outcome
Other
675 stars 62 forks source link

change of no-error path behavior leading to maybe-uninitialized warning #264

Open slymz opened 2 years ago

slymz commented 2 years ago

Repro and detailed description here:

https://godbolt.org/z/YG6e8q3Y5

Excerpt:

using Result =
    outcome::result<std::tuple<int, std::string>, InHouseErrorz *, MyNVP>;

auto foo() {
    Result r{1, "a"};
    // r = nullptr; //< UNCOMMENT to eliminate warning
    r = {2, "b"};
    return r.assume_value();
}

Very likely that this is a GCC issue (in fact, can't be reproduced in trunk). Yet, it is a curious phenomenon and causing production hassle with our boost upgrade. I am wondering if this is an expected change with later Outcome versions, or worse and crucially if the usage in the reproduction code is somewhat making incorrect assumptions.

Or, if there is confirmation this is just a silly GCC bug, it'd be a good enough resolution.

thanks

ned14 commented 2 years ago

I've seen this in the work code base as well, and I too would like it to go away. I'll hopefully create some time to do it soon. Thanks for the report.

BurningEnlightenment commented 1 year ago

Possibly related, I've started to observe clang-analyzer-core.uninitialized.Assign diagnostics being triggered by OUTCOME_TRY:

D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\status-code/status_code.hpp:378:18: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
        , _value(static_cast<status_code_storage &&>(o)._value)
[...]
D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:197:21: note: expanded from macro 'OUTCOME_TRYV2_SUCCESS_LIKELY'
    auto unique##_f(::OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique)));                                                \
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:95:10: note: Calling 'basic_result::as_failure'
  return static_cast<T &&>(v).as_failure();
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/experimental/../basic_result.hpp:707:12: note: Calling 'failure<system_error2::errored_status_code<system_error2::erased<long long>>>'
    return failure(static_cast<basic_result &&>(*this).assume_error(), hooks::spare_storage(this));
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/experimental/../success_failure.hpp:245:10: note: Calling constructor for 'failure_type<system_error2::errored_status_code<system_error2::erased<long long>>, void>'
  return failure_type<std::decay_t<EC>>{static_cast<EC &&>(v), spare_storage};
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It looks like clang-tidy cannot deduce that .has_failure()assume_error() is initialized holds.

full log ``` D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\status-code/status_code.hpp:378:18: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign] , _value(static_cast(o)._value) ^ D:\devel\source\deeplex\deeplog\src\dplx\dlog\file_database.cpp:94:5: note: Taking true branch DPLX_TRY(fetch_content_impl()); ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\dplx/dp/disappointment.hpp:194:23: note: expanded from macro 'DPLX_TRY' #define DPLX_TRY(...) OUTCOME_TRY(__VA_ARGS__) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:336:26: note: expanded from macro 'OUTCOME_TRY' #define OUTCOME_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:155:29: note: expanded from macro 'OUTCOME_TRY_CALL_OVERLOAD' OUTCOME_TRY_OVERLOAD_GLUE(OUTCOME_TRY_OVERLOAD_MACRO(name, OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__)) ^ note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:151:50: note: expanded from macro 'OUTCOME_TRY_OVERLOAD_MACRO1' #define OUTCOME_TRY_OVERLOAD_MACRO1(name, count) OUTCOME_TRY_OVERLOAD_MACRO2(name, count) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:150:50: note: expanded from macro 'OUTCOME_TRY_OVERLOAD_MACRO2' #define OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count ^ note: expanded from here D:\devel\source\deeplex\deeplog\src\dplx\dlog\file_database.cpp:96:32: note: Assuming the condition is false for (auto &recordContainer : mContents.record_containers) ^ D:\devel\source\deeplex\deeplog\src\dplx\dlog\file_database.cpp:120:11: note: Calling 'file_database_handle::retire_to_storage' (void)retire_to_storage(mContents); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\src\dplx\dlog\file_database.cpp:337:5: note: Taking true branch DPLX_TRY(auto &&outStream, ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\dplx/dp/disappointment.hpp:194:23: note: expanded from macro 'DPLX_TRY' #define DPLX_TRY(...) OUTCOME_TRY(__VA_ARGS__) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:336:26: note: expanded from macro 'OUTCOME_TRY' #define OUTCOME_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:155:29: note: expanded from macro 'OUTCOME_TRY_CALL_OVERLOAD' OUTCOME_TRY_OVERLOAD_GLUE(OUTCOME_TRY_OVERLOAD_MACRO(name, OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__)) ^ note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:151:50: note: expanded from macro 'OUTCOME_TRY_OVERLOAD_MACRO1' #define OUTCOME_TRY_OVERLOAD_MACRO1(name, count) OUTCOME_TRY_OVERLOAD_MACRO2(name, count) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:150:50: note: expanded from macro 'OUTCOME_TRY_OVERLOAD_MACRO2' #define OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count ^ note: expanded from here D:\devel\source\deeplex\deeplog\src\dplx\dlog\file_database.cpp:341:5: note: Taking false branch DPLX_TRY(dp::encode(outStream, contents)); ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\dplx/dp/disappointment.hpp:194:23: note: expanded from macro 'DPLX_TRY' #define DPLX_TRY(...) OUTCOME_TRY(__VA_ARGS__) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:336:26: note: expanded from macro 'OUTCOME_TRY' #define OUTCOME_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:155:29: note: expanded from macro 'OUTCOME_TRY_CALL_OVERLOAD' OUTCOME_TRY_OVERLOAD_GLUE(OUTCOME_TRY_OVERLOAD_MACRO(name, OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__)) ^ note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:151:50: note: expanded from macro 'OUTCOME_TRY_OVERLOAD_MACRO1' #define OUTCOME_TRY_OVERLOAD_MACRO1(name, count) OUTCOME_TRY_OVERLOAD_MACRO2(name, count) ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:150:50: note: expanded from macro 'OUTCOME_TRY_OVERLOAD_MACRO2' #define OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count ^ note: expanded from here D:\devel\source\deeplex\deeplog\src\dplx\dlog\file_database.cpp:341:5: note: Calling 'try_operation_return_as>, outcome_v2::experimental::policy::status_code_throw>, void>>>' DPLX_TRY(dp::encode(outStream, contents)); ^ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\dplx/dp/disappointment.hpp:194:23: note: expanded from macro 'DPLX_TRY' #define DPLX_TRY(...) OUTCOME_TRY(__VA_ARGS__) ^~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:336:26: note: expanded from macro 'OUTCOME_TRY' #define OUTCOME_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:155:29: note: expanded from macro 'OUTCOME_TRY_CALL_OVERLOAD' OUTCOME_TRY_OVERLOAD_GLUE(OUTCOME_TRY_OVERLOAD_MACRO(name, OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__)) ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: (skipping 5 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:300:36: note: expanded from macro 'OUTCOME_TRY_INVOKE_TRY1' #define OUTCOME_TRY_INVOKE_TRY1(a) OUTCOME_TRYV(a) ^~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:221:27: note: expanded from macro 'OUTCOME_TRYV' #define OUTCOME_TRYV(...) OUTCOME_TRYV2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, deduce, __VA_ARGS__) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:197:21: note: expanded from macro 'OUTCOME_TRYV2_SUCCESS_LIKELY' auto unique##_f(::OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast(unique))); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/try.hpp:95:10: note: Calling 'basic_result::as_failure' return static_cast(v).as_failure(); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/experimental/../basic_result.hpp:707:12: note: Calling 'failure>>' return failure(static_cast(*this).assume_error(), hooks::spare_storage(this)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\devel\source\deeplex\deeplog\build\x64-windows-clang\vcpkg_installed\x64-windows-static\include\outcome/experimental/../success_failure.hpp:245:10: note: Calling constructor for 'failure_type>, void>' return failure_type>{static_cast(v), spare_storage}; ```