#1038134 g++-12: Conditional compilation error in optimized mode

Package:
g++-12
Source:
g++-12
Description:
GNU C++ compiler
Submitter:
Michael Ivanov
Date:
2023-07-22 10:09:02 UTC
Severity:
normal
Tags:
#1038134#5
Date:
2023-06-15 19:50:52 UTC
From:
To:
Dear Maintainer,

When I compile c++ code which has an error (method invoked on
null class pointer) the following problem occurs: the actual
call does not crash, since 'this' pointer is not really used
in called method, but conditional below works incorrectly.
Here's the simplified code in question:

      else {
         np = getstr(cp);
         if (!::strcasecmp(np, "info"))
            current = channel->get_class(ErrorCode::Info);
         else if (!::strcasecmp(np, "internal"))
            current = channel->get_class(ErrorCode::Internal);
	 . . . . . .
         else {
            Log::Error("%s:%d: unrecognized error class [%s]", _fname, _lineno, np);
            current = 0;
            continue;
         }
      }

      if (!channel || !current)
         continue;

      np = getstr(cp);

channel can be 0 after first 'else', but get_class() does not crash,
since it just returns a computed pointer to array item inside the
object, so that current is set to some invalid value like 0x120.
It proceeds to the 'if (!channel || !current)' conditional and
with given values (channel == 0, current == 0x120) continue should
be executed. Instead the control falls through to the next line.

This error occurs only when the code is compiled with -O2 or -O3.
When -O0 is used, the conditional works properly. The error is
not observed when compiled with g++-11.

The error also dissappears when I fix my error (replace first
'else {' by 'else if (channel) {').

If this information is of any interest I can send combined
c++/assembly listings for cases with and without optimization.

Best regards,

#1038134#10
Date:
2023-07-10 13:13:50 UTC
From:
To:
please recheck with the gcc-12 and gcc-13 packages from unstable.  Also please
try to check with a standalone test case.

#1038134#17
Date:
2023-07-22 09:55:31 UTC
From:
To:
I don't understand how this is a bug. Calling a member function on
a null pointer is clearly UB.

There is already a flag to support non-standard programs like this
(-fno-delete-null-pointer-checks), but it's not enabled by default,
of course.