https://bugs.kde.org/show_bug.cgi?id=472329

--- Comment #9 from m <[email protected]> ---
I found a similar code with two cpp files, that reproduces since G++-12, up to
G++-15.

       │ File: ./main.cpp
  01   │ #include <iostream>
  02   │ #include <map>
  03   │ #include <memory>
  04   │ #include <optional>
  05   │ #include <variant>
  06   │ #include <vector>
  07   │ #include <string>
  08   │ 
  09   │ void opaque_barrier(void*);
  10   │ 
  11   │ struct DataContainer {
  12   │     std::map<int, std::vector<int>> items;
  13   │     int64_t field_primary{0};
  14   │     std::optional<int64_t> field_secondary;
  15   │ };
  16   │ 
  17   │ size_t GetContainerSize(const DataContainer&);
  18   │ 
  19   │ std::optional<int64_t> ExtractValue(const DataContainer& obj, bool
use_primary)
  20   │ {
  21   │     if (use_primary) {
  22   │         return std::optional<int64_t>{obj.field_primary};
  23   │     } else {
  24   │         return obj.field_secondary;
  25   │     }
  26   │ }
  27   │ 
  28   │ std::variant<int, std::string> ExecuteLogic()
  29   │ {
  30   │     DataContainer input_data; 
  31   │     int internal_id{1234};
  32   │     int64_t base_threshold{14769726};
  33   │     bool flag_allow_extra{true};    
  34   │     bool flag_mode_selector{false}; 
  35   │ 
  36   │     opaque_barrier(&internal_id);
  37   │     opaque_barrier(&input_data);
  38   │     opaque_barrier(&base_threshold);
  39   │     opaque_barrier(&flag_allow_extra);
  40   │     opaque_barrier(&flag_mode_selector);
  41   │ 
  42   │     DataContainer state_buffer; // Default initialized
  43   │ 
  44   │     int64_t calculated_target = base_threshold -
ExtractValue(input_data, flag_mode_selector).value_or(0);
  45   │ 
  46   │     if (!flag_allow_extra && calculated_target > 0) {
  47   │         return std::string{};
  48   │     }
  49   │ 
  50   │     opaque_barrier(&input_data);
  51   │ 
  52   │     if (calculated_target <= 0) {
  53   │         return std::string{};
  54   │     }
  55   │ 
  56   │     int64_t current_buffer_val = ExtractValue(state_buffer,
flag_mode_selector).value_or(0);
  57   │ 
  58   │     // Valgrind often reports the error at this comparison under -O2
  59   │     if (calculated_target > current_buffer_val) {
  60   │         return std::string(); 
  61   │     }
  62   │ 
  63   │     if (GetContainerSize(state_buffer) > 100) {
  64   │         std::cout << "Threshold exceeded" << std::endl;
  65   │     }
  66   │ 
  67   │     return std::string{};
  68   │ }
  69   │ 
  70   │ int main()
  71   │ {
  72   │     auto result = ExecuteLogic();
  73   │     return 0;
  74   │ }


       │ File: ./helper.cpp
  01   │ #include <map>
  02   │ #include <optional>
  03   │ #include <vector>
  04   │ #include <cstdint>
  05   │ 
  06   │ struct DataContainer {
  07   │     std::map<int, std::vector<int>> items;
  08   │     int64_t field_primary{0};
  09   │     std::optional<int64_t> field_secondary;
  10   │ };
  11   │ 
  12   │ // Use an empty function in a separate TU to prevent 
  13   │ // the compiler from performing constant folding.
  14   │ void opaque_barrier(void* p) {}
  15   │ 
  16   │ size_t GetContainerSize(const DataContainer& obj) 
  17   │ {
  18   │     return 0;
  19   │ }

It only reproduces with -O2:

```sh
g++-15 ./main.cpp ./helper.cpp -o ./exe -O2 -g2 -o ./exe && valgrind --quiet
--error-exitcode=1 ./exe ; echo $?
==42923== Conditional jump or move depends on uninitialised value(s)
==42923==    at 0x4001589: ExecuteLogic[abi:cxx11]() (main.cpp:59)
==42923==    by 0x40011DE: main (main.cpp:72)
==42923== 
1

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to