Created attachment 1954800 [details] Standalone repro for the issue being reported Description of problem: -Wmaybe-uninitialized is not being suppressed for a system header at optimization level -O1 and above. The attached code comes from the QuantLib project and I have modified it to demonstrate the issue as a self-contained repro. Version-Release number of selected component (if applicable): 1. gcc-toolset-12-gcc.x86_64 12.1.1-3.4.el8_7 @rhel-8-for-x86_64-appstream-rpms 2. boost-devel.x86_64 1.66.0-13.el8 @rhel-8-for-x86_64-appstream-rpms Steps to Reproduce: 1. First, compile the attached file with -Wmaybe-uninitialized and -O0 to confirm no warnings: $ g++ -Wmaybe-uninitialized -O0 -c main.cpp 2. Next, compile the attached file with -Wmaybe-uninitialized -O1 and confirm that the following warning is emitted: $ g++ -Wmaybe-uninitialized -O1 -c main.cpp In file included from /usr/include/boost/function/detail/maybe_include.hpp:22, from /usr/include/boost/function/detail/function_iterate.hpp:14, from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52, from /usr/include/boost/function.hpp:70, from main.cpp:1: In member function ‘void boost::function1<R, T1>::move_assign(boost::function1<R, T1>&) [with R = double; T0 = double]’, inlined from ‘void boost::function1<R, T1>::swap(boost::function1<R, T1>&) [with R = double; T0 = double]’ at /usr/include/boost/function/function_template.hpp:858:22, inlined from ‘typename boost::enable_if_c<(! boost::is_integral<Functor>::value), boost::function<R(T0)>&>::type boost::function<R(T0)>::operator=(Functor) [with Functor = FilonIntegral::integrate(const boost::function<double(double)>&, double, double) const::<lambda(double)>; R = double; T0 = double]’ at /usr/include/boost/function/function_template.hpp:1114:22, inlined from ‘virtual double FilonIntegral::integrate(const boost::function<double(double)>&, double, double) const’ at main.cpp:110:59: /usr/include/boost/function/function_template.hpp:986:13: warning: ‘<unnamed>.boost::function<double(double)>::<unnamed>.boost::function1<double, double>::<anonymous>.boost::function_base::functor’ may be used uninitialized [-Wmaybe-uninitialized] 986 | this->functor = f.functor; | ^~~~ /usr/include/boost/function/function_template.hpp: In member function ‘virtual double FilonIntegral::integrate(const boost::function<double(double)>&, double, double) const’: /usr/include/boost/function/function_template.hpp:1114:5: note: ‘<anonymous>’ declared here 1114 | self_type(f).swap(*this); | ^~~~~~~~~~~~ Actual results: As shown above Expected results: I expect no warning to be emitted for boost headers installed in /usr/include, because as far as I understand, /usr/include is a system header directory by default; i.e. implicitly passed as `-isystem /usr/include` to the compiler. Additional info: I am running Red Hat Enterprise Linux release 8.7 (Ootpa)
Hi, thanks for the test. That a middle-end warning such as -Wmaybe-uninitialized triggers with optimizations turned on but not when optimizations are turned off is normal. You can visit <https://developers.redhat.com/blog/2019/03/13/understanding-gcc-warnings-part-2#limitations_of_middle_end_warnings> for more information on that subject. I could reproduce the problem with boost-devel-1.66 but not boost-devel-1.78. Turns out that boost has disabled the warning; git log function_template.hpp shows commit b75386f628b46f1060a20b6e015931bac37b7da7 (origin/feature/drone) Author: Peter Dimov <pdimov> Date: Sun Feb 12 04:50:04 2023 +0200 Avoid -Wuninitialized under GCC 11.3 commit 9229ed30103df59a4f989ca0235b0d1026bf6e1c Author: Peter Dimov <pdimov> Date: Sun Feb 12 04:47:38 2023 +0200 Avoid another -Wmaybe-uninitialized under GCC 11/12 commit 16fca8368b5da14c4bcad977c2738dc6e482e1b7 (tag: boost-1.81.0.beta1, tag: boost-1.81.0, tag: boost-1.80.0.beta1, tag: boost-1.80.0, origin/feature/issue-42) Author: Peter Dimov <pdimov> Date: Mon May 30 20:25:13 2022 +0300 Keep -Wmaybe-uninitialized disabled commit 4cf7c718b873223cbab6f8188bea2034f27ba99d Merge: 389f886 5b4e279 Author: Peter Dimov <pdimov> Date: Mon May 30 19:56:08 2022 +0300 Merge branch 'gcc12-Wuninitialized' of https://github.com/jngrad/boost-function into feature/issue-42 commit abc1bf9b4ae3f45251d17b451c69c3e79dfd0cf6 (origin/feature/update-ci) Author: Peter Dimov <pdimov> Date: Mon May 30 18:44:07 2022 +0300 Extend GCC 11 workaround to GCC 12 as well commit 5b4e2797a28f9477d2df5fa915409dac73ff00c6 Author: Jean-Noël Grad <jgrad.de> Date: Mon May 30 16:16:41 2022 +0200 Avoid -Wuninitialized warnings in GCC 12 commit 277757befc321bda3b9d8038ee59ae6e4616cdca Author: Peter Dimov <pdimov> Date: Thu Dec 16 06:18:06 2021 +0200 Disable -Wmaybe-uninitialized in function_template.hpp for GCC 11 commit 7c90434317894f1a0c63c7a395ddf569eff1d308 Author: Romain Geissler <romain.geissler> Date: Fri Mar 27 18:56:14 2020 +0000 Avoid -Wmaybe-uninitialized warnings in gcc (issue #27). so with newer boost you wouldn't see the warning. If you can't update boost, you can do #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #include <boost/function.hpp> #pragma GCC diagnostic pop in your project to suppress the warning. Just for the record, GCC started warning with commit 6feb628a706e86eb3f303aff388c74bdb29e7381 Author: Martin Sebor <msebor> Date: Fri Jul 2 16:16:31 2021 -0600 Improve warning suppression for inlined functions [PR98512].
Hi Marek, thanks very much for looking into this and for the explanations. I understand that the optimization level affects which compiler warnings are generated, but my question is why aren't those warnings suppressed for system headers? According to the GCC documentation[1], "All warnings, other than those generated by ‘#warning’ (see Diagnostics), are suppressed while GCC is processing a system header." Is this not true for gcc-toolset-12? I read the article that you linked and it doesn't specifically say that the compiler will not suppress warnings for system headers, so I still don't expect to see any warnings from the boost headers installed in /usr/include, which is a system header directory. Can you help clarify why the warnings are not being suppressed? [1] https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html
Sorry for the slow response. I think you're right on the money, and there's something strange going on. It all seems to be due to 106 f1 = [](double x) -> double { return std::sin(x); }; being inlined, the problem doesn't reproduce with -fno-inline. We have an inlining context containing locations for each call site along the inlining stack: struct inlining_info. It has a stack of locations, and a flag that says whether all of them come from a system header. If so, we don't warn: 1548 if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs) 1549 /* Bail if the warning is not to be reported because all locations 1550 in the inlining stack (if there is one) are in system headers. */ 1551 return false; but in this test diagnostic->m_iinfo.m_allsyslocs is false because the inlining causes that the outermost context is the bz.C file, which is not a system header. Reduced to: # 0 "" 3 struct function_base { has_trivial_copy_and_destroy() const; int functor; }; struct function1 : function_base { swap(function1) { has_trivial_copy_and_destroy(); } }; struct function : function1 { template <typename Functor> operator=(Functor) { swap(*this); } }; # 4 "" struct FilonIntegral { double integrate() const; }; double FilonIntegral::integrate() const { function f1; f1 = [] {}; return 0; } This needs to be fixed upstream first (if it is indeed a bug). It is not special to the GCC Toolset.
When you say upstream, do you mean in the main GCC repository? If so, should I file a bug report with GCC, or is it something that RedHat could help coordinate?
> When you say upstream, do you mean in the main GCC repository? Correct. I've opened <https://gcc.gnu.org/PR109559>. Let's see what other developers think about it. And let's move the discussion to the upstream PR.