Bug 105749 - Bogus maybe-uninitialized when using std::optional, regex and sstream
Summary: Bogus maybe-uninitialized when using std::optional, regex and sstream
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2022-05-27 10:13 UTC by hi+gccbugs
Modified: 2024-03-06 12:53 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 10.3.0, 12.2.1, 13.0, 7.5.0
Last reconfirmed: 2022-09-22 00:00:00


Attachments
t.ii reproducer (270.50 KB, application/gzip)
2022-05-27 10:13 UTC, hi+gccbugs
Details

Note You need to log in before you can comment on or make changes to this bug.
Description hi+gccbugs 2022-05-27 10:13:05 UTC
Created attachment 53044 [details]
t.ii reproducer

Compiling following with -Wall -Werror -Os produces bogus 
maybe-unitialized warning


/tmp/t.cpp: In function ‘void t(const string&)’:
/tmp/t.cpp:12:51: error: ‘*(int*)((char*)&port + offsetof(std::optional<int>,std::optional<int>::<unnamed>.std::_Optional_base<int, true, true>::<unnamed>))’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   12 |         reqb << "Host: " << port.value_or(443) << "\r\n";



Attaching .ii (tar.gz due to attachment limit) file from 11.2.0, but it is also reproducible on trunk in godbolt: https://godbolt.org/z/ha3vn61n9

Interesting that commenting unrelated parts or changing them slightly makes
warning go away.


#include <regex>
#include <optional>
#include <sstream>

void t(const std::string& i) {
        const std::regex re("^$"); //removing this works

        std::optional<int> port(i.length() > 0 ? std::make_optional(std::strtol("99", nullptr, 10)) : std::nullopt);

        std::ostringstream reqb;
        reqb << "GET /" << i << " HTTP/1.1" << "\r\n"; //removing this works
        reqb << "Host: " << port.value_or(443) << "\r\n";
}
Comment 1 Andrew Pinski 2022-06-22 20:20:21 UTC
>Interesting that commenting unrelated parts or changing them slightly makes
warning go away.

Most likely inlining changes with those being there vs not being there.
Comment 2 Andrew Pinski 2022-06-22 20:23:10 UTC
<source>: In function 'void t(const std::string&)':
<source>:13:51: warning: '*(int*)((char*)&port + offsetof(std::optional<int>,std::optional<int>::<unnamed>.std::_Optional_base<int, true, true>::<unnamed>))' may be used uninitialized [-Wmaybe-uninitialized]
   13 |         reqb << "Host: " << port.value_or(443) << "\r\n";
      |                                                   ^~~~~~
<source>:9:28: note: '*(int*)((char*)&port + offsetof(std::optional<int>,std::optional<int>::<unnamed>.std::_Optional_base<int, true, true>::<unnamed>))' was declared here
    9 |         std::optional<int> port(i.length() > 0 ? std::make_optional(std::strtol("99", nullptr, 10)) : std::nullopt);
      |                            ^~~~
Comment 3 Andrew Pinski 2022-06-22 20:24:37 UTC
Note in GCC 10.3.0 we got:
<source>: In function 'void t(const string&)':
<source>:13:51: warning: 'port' may be used uninitialized in this function [-Wmaybe-uninitialized]
   13 |         reqb << "Host: " << port.value_or(443) << "\r\n";
      |                                                   ^~~~~~
Comment 4 Richard Biener 2022-09-22 13:25:14 UTC
Confirmed on the GCC 12 branch but on master the diagnostic only shows with -O1 now ...