Re: Expected warning maybe-uninitialized does not appear using g++13.2.0?
On Thu, 21 Dec 2023, David Malcolm via Gcc wrote: On Wed, 2023-12-20 at 11:16 -0800, Eric Batchelor wrote: Hello, I unintentionally stumbled upon some strange behaviour that occurred due to a typo. I reproduced the behaviour where an object (std::string in my case) can be passed to a function by reference, uninitialized, WITHOUT a compiler warning. Changing the code to pass the object by value DOES emit the warning. I don't think the compiled code is incorrect, it segfaults presumably due to uninitialized members. I understand there may seldom be a reason to use uninitialized objects, so "don't do that," but as I said this was unintentional and it seems that it should have generated a warning, which have saved some head-scratching. Code to reproduce: #include std::string f(std::string ) { s.append("x"); return s; } int main() { std::string a = f(a); } Compile and run (no warning): $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic - Wextra && ./uninit_obj Segmentation fault (core dumped) No difference whether using -O0 (or 1 2 3) As I understand it, -Wmaybe-uninitialized is purely intraprocedural i.e. it works within each individual function, without considering the interactions *between* functions. If you compile #include static std::string f(std::string ) { s.append("x"); return s; } void g() { std::string a = f(a); } with -O3, by the time we get to the uninit pass, function g starts with void g () { size_type __dnew; struct string a; [...] [local count: 1073741824]: _26 = a._M_string_length; if (_26 == 4611686018427387903) which should not require any interprocedural logic. -- Marc Glisse
Re: Expected warning maybe-uninitialized does not appear using g++13.2.0?
On Wed, 2023-12-20 at 11:16 -0800, Eric Batchelor wrote: > Hello, I unintentionally stumbled upon some strange behaviour that > occurred due to a typo. > I reproduced the behaviour where an object (std::string in my case) > can > be passed to a function by reference, uninitialized, WITHOUT a > compiler > warning. > Changing the code to pass the object by value DOES emit the warning. > I don't think the compiled code is incorrect, it segfaults presumably > due to uninitialized members. > I understand there may seldom be a reason to use uninitialized > objects, > so "don't do that," but as I said this was unintentional and it seems > that it should have generated a warning, which have saved some > head-scratching. > > Code to reproduce: > > #include > std::string f(std::string ) { > s.append("x"); > return s; > } > int main() { > std::string a = f(a); > } > > Compile and run (no warning): > > $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic - > Wextra > && ./uninit_obj > Segmentation fault (core dumped) > > No difference whether using -O0 (or 1 2 3) As I understand it, -Wmaybe-uninitialized is purely intraprocedural i.e. it works within each individual function, without considering the interactions *between* functions. FWIW, -fanalyzer does attempt to model interprocedural interactions, but doesn't yet work properly on C++ code. For your example, it happens to generate some warnings, but the wording is really vague; see: https://godbolt.org/z/a1q7xYMjb and it might well be getting other things wrong (as I said, it doesn't yet properly work on C++). Dave > > If I change the function to pass by value, std::string f(std::string > s), > and rerun, I get the expected compiler warning: > > $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic - > Wextra > && ./uninit_obj > uninit_obj.cpp: In function 'int main()': > uninit_obj.cpp:7:22: warning: 'a' may be used uninitialized > [-Wmaybe-uninitialized] > 7 | std::string a = f(a); > [...] > terminate called after throwing an instance of 'std::bad_alloc' > what(): std::bad_alloc > Aborted (core dumped) > > Output from g++ -v: > > Using built-in specs. > COLLECT_GCC=g++ > COLLECT_LTO_WRAPPER=/usr/local/gcc13/libexec/gcc/x86_64-pc-linux- > gnu/13.2.0/lto-wrapper > Target: x86_64-pc-linux-gnu > Configured with: ../gcc-13.2.0/configure --disable-multilib > --enable-languages=c,c++ --prefix=/usr/local/gcc13 --program-suffix=- > 13 > --enable-libstdcxx-backtrace=yes > Thread model: posix > Supported LTO compression algorithms: zlib > gcc version 13.2.0 (GCC) > > Thanks >
Expected warning maybe-uninitialized does not appear using g++13.2.0?
Hello, I unintentionally stumbled upon some strange behaviour that occurred due to a typo. I reproduced the behaviour where an object (std::string in my case) can be passed to a function by reference, uninitialized, WITHOUT a compiler warning. Changing the code to pass the object by value DOES emit the warning. I don't think the compiled code is incorrect, it segfaults presumably due to uninitialized members. I understand there may seldom be a reason to use uninitialized objects, so "don't do that," but as I said this was unintentional and it seems that it should have generated a warning, which have saved some head-scratching. Code to reproduce: #include std::string f(std::string ) { s.append("x"); return s; } int main() { std::string a = f(a); } Compile and run (no warning): $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic -Wextra && ./uninit_obj Segmentation fault (core dumped) No difference whether using -O0 (or 1 2 3) If I change the function to pass by value, std::string f(std::string s), and rerun, I get the expected compiler warning: $ g++ -o uninit_obj uninit_obj.cpp -std=c++23 -Wall -Wpedantic -Wextra && ./uninit_obj uninit_obj.cpp: In function 'int main()': uninit_obj.cpp:7:22: warning: 'a' may be used uninitialized [-Wmaybe-uninitialized] 7 | std::string a = f(a); [...] terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted (core dumped) Output from g++ -v: Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/local/gcc13/libexec/gcc/x86_64-pc-linux-gnu/13.2.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-13.2.0/configure --disable-multilib --enable-languages=c,c++ --prefix=/usr/local/gcc13 --program-suffix=-13 --enable-libstdcxx-backtrace=yes Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.2.0 (GCC) Thanks