0

I am trying to detect the following undefined behavior:

% cat undef.cxx
#include <iostream>

class C
{
    int I;
public:
    int getI() { return I; }
};

int main()
{
    C c;
    std::cout << c.getI() << std::endl;

    return 0;
}

For some reason all my naive attempts have failed so far:

% g++ -Wall -pedantic -o undef -fsanitize=undefined undef.cxx && ./undef
21971

same goes for:

% clang++ -Weverything -o undef -fsanitize=undefined undef.cxx && ./undef
0

Is there a way to use a magic flag in gcc/clang to report a warning/error for the above code at compile time ? at run time ?

References:

% g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110

and

% clang++ --version
Debian clang version 11.0.1-2
malat
  • 12,152
  • 13
  • 89
  • 158
  • 2
    https://stackoverflow.com/questions/2099692/easy-way-find-uninitialized-member-variables – KamilCuk Nov 09 '21 at 14:15
  • https://godbolt.org/z/bP55GdvYv – Marek R Nov 09 '21 at 14:28
  • This question is **not** a duplicate of the question above, since really what is important is understanding combination of `-O2` with `-Wuninitialized` – malat Nov 09 '21 at 15:04
  • `-O2` has no impact on `-Wuninitialized`. `-O2` only selects optimizations. Optimizer can detect UB and drop code branches which are leading to undefined behavior, but will not report anything that some code was dropped because of UB found. `-Wuninitialized` when enabled will be reporting problem no matter what is current optimization level. – Marek R Nov 09 '21 at 17:51
  • @MarekR in this case how do you explain [this](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639), same question for the above code (try with and without `-O2`) ? – malat Nov 09 '21 at 17:59
  • You can use `-Og` (optimize in such way that debugging is not impacted) then this warning is triggered. I'm surprised that this warning is not reported for `-O0`. What is strange clang fails in this case completely. clang-tidy should find this. I still think this is a duplicate, but hear you go - reopened. – Marek R Nov 09 '21 at 18:19

1 Answers1

0

Turns out my g++ version seems to handle it just fine, all I was missing is the optimization flag:

% g++ -O2 -Wall -pedantic -o undef -fsanitize=undefined undef.cxx  && ./undef
undef.cxx: In function ‘int main()’:
undef.cxx:7:25: warning: ‘c.C::I’ is used uninitialized in this function [-Wuninitialized]
    7 |     int getI() { return I; }
      |                         ^
0

This is clearly documented upstream:

Because these warnings depend on optimization, the exact variables or elements for which there are warnings depend on the precise optimization options and version of GCC used.

Here is upstream 'meta'-bug to track all those related issues:

malat
  • 12,152
  • 13
  • 89
  • 158
  • To detect many types of Undefined Behaviour the compiler needs to do code flow analysis. This is expensive (slow); not necessary for a debug build and also has to be done for optimisation(s); so it is not usually done for non-optimised builds. – Richard Critten Nov 09 '21 at 14:26
  • I've learned something new today, – malat Nov 09 '21 at 14:33