https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121735

            Bug ID: 121735
           Summary: Optimization level O2 triggers false warning about
                    uninitialized usage whereas O1 and O3 are fine.
           Product: gcc
           Version: 15.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: b.stolk at gmail dot com
  Target Milestone: ---

The gcc compiler (O2 only) will warn with "maybe used unitialized" whereas the
code does not use any variable uninitialized.

I have tested this via godbolt, on 15.2.1 and also gcc-trunk, both of which
trigger a false warning about maybe uninitialized variable. Clang does not
warn.

I have created a minimal example code to trigger it.

I have found the following conditions that require it to trigger:

* It needs to be compiled -O2, whereas -O1 and -O3 do not trigger it.
* It needs to use the results in an externally defined function, if I place the
implementation in the file, it no longer triggers. See the two ifdef macros.

Here is the code that triggers it (gcc -c -Wall -Wextra) 

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

typedef struct {
        float x;
        float y;
} pt_t;

typedef struct
{
        int  len;
        pt_t v[8];
} poly_t;

#if 1
// Calling an extern func is a prerequisit for the bug.
extern void print_pt(pt_t p);
#else
// No compiler warning when using this.
void print_pt(pt_t p) { fprintf(stderr, "%f %f\n", p.x, p.y); }
#endif

void process_poly(const poly_t* poly)
{
        // Two uninitialized arrays.
        float rngx[2];
        float rngy[2];

        const int len = poly->len;
        assert(len > 0);

        for (int i=0; i<len; ++i)
        {
                if (i==0 || poly->v[i].x < rngx[0]) rngx[0] = poly->v[i].x;
                if (i==0 || poly->v[i].x > rngx[1]) rngx[1] = poly->v[i].x;
                if (i==0 || poly->v[i].y < rngy[0]) rngy[0] = poly->v[i].y;
                if (i==0 || poly->v[i].y > rngy[1]) rngy[1] = poly->v[i].y;
        }

        const pt_t q = { rngx[1] - rngx[0], rngy[1] - rngy[0] };
#if 0
        // No compiler warning on uninitialized use of rngx[0] and rngy[0]
        fprintf(stderr, "%f %f\n", q.x, q.y);
#else
        // compiler warning on unintialized use. (But only when compiling -O2)
        print_pt(q);
#endif
}

The incorrect output:

<source>: In function 'process_poly':
<source>:27:15: warning: 'rngx[0]' may be used uninitialized
[-Wmaybe-uninitialized]
   27 |         float rngx[2];
      |               ^~~~
<source>:28:15: warning: 'rngy[0]' may be used uninitialized
[-Wmaybe-uninitialized]
   28 |         float rngy[2];
      |     

The warning is incorrect, and it is strange that merely changing optimization
level will change what the compiler thinks of the code correctness.

One more remark: dropping down to gcc 14, the warning is stronger:
"uninitialized use" as opposed to the weaker "maybe uninitialized."

Here is a godbolt link that shows the incorrect warning, including for
gcc-trunk:

https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1AB9U8lJL6yAngGVG6AMKpaAVxYM9DgDJ4GmADl3ACNMYhAAVg1SAAdUBUJbBmc3Dz04hJsBX38gllDwqItMKyyGIQImYgIU908uYtKkiqqCHMCQsMjohUrq2rSG3tb2vILugEoLVFdiZHYOAFIAJgBmP2Q3LABqRdXHXvRaPGCAOgQ97EWNAEEV9YZN1x29g4J8VHPL67u1ja3MLt9kwFEpql9Vldbj8CABPGKYLBUba9Yiuay7ADsACEftcAJxUWioJgEbaqPa46EaQnE0nbWGUvGYgAi2xiBGMBCZ1JucIRSJRBDR1mZVJu20lUslfjJ23oDB5EulUo5XO2ADdFhFsQAObUspWLVnslywrlG6F/ZFcH4Aejt20cYmORm2hm2mFUBDCDG2VFcj22eAU7vZxDCmAAjq4Q4R/SRtgQEIDgq5gKcfl6fcQ/RrUHh0OHZcYORA1WSYhMjWsSkp7Y6AqhtmgWDE6GFtgB3KoMPzAbspv2uBJu5MhzO3fOF4uCUsEcucysTLHY/0xYiyqgQQ5hMi7ZbLFYRZHHqjaxyKw%2BkdmnVQ3mKnWHV1Zr42Gq2rBx4c%2B86dFjdUHmUFSzNCA0AYXpTVoc0CAAKmg58xTxGkHW2AAVLtm0DPxEjEPAAC9EXdYhiCYWEFEnO4aSJEkyVzYAKR1I8IkNV8UNpOjtgYxlmINS1qPxCCoNleVGCBNk4hggBaS4FUtfEQTBBcFSBbBtg0F9xQ4/hiG2CBRLwPYWQ0Slg1eeTXwPXFlmxPBq2pfFjW0mkCR/fSjNWNiTKxRxjUcRDZMhLUdSM1i7yBAKGKY7FTNYldou1WKDQkwLLhCuyDTvBS3ORAzjOMjRfP8tLgqSsKWQiy5uKMGLbXimrGKS%2Bq2WM0rsAyirsvYxzco8gqvKK/ySqk2Ego68qsthSLGt45KGp4pK4tarz2s6qacppdz8q8wrisxALRvG9bwum6rFp1FqEqMOaWtSo70sm06ctZFDBOEysl22KNUucxq6pS6T/qWg0bwu7E7qB8HlqxNjtOtDSOLQpsW1QNsOz0ntc37bYBG2HC%2BxsfCiKLEdAVQZFEp1GHDCLaH%2BMcqgNy3Hd3j3G8ViPZYTwPE8LyvZYbyjO8hafLS8VrWh60ctDW3behMd7HG8YJonjhJ/GlFOfTsVcMkBBgwdxLlugcekgB5ZYHME5m5zLKNxc/b9fzuV7bg4KZaE4CJeE8DgtFIVBOAChQZjmQF7h4UgCE0D2pgAaxAVZVlOZO0/TjOADZ9E4SRfdjwPOF4BQQGiGP/Y90g4FgJATYV8hKDrrpkGALgIkFmhaBzEuIGCAvgj8KpYU4KOB%2BYYhYXN4JtEwawR94Vs2EEc2GBggusDTYBnVoKX59ILAWEMYBxAr/e8Ajaw8A1TAS9Pr1Z71hYo9lEoC%2BOYIyIn5wsAL4U8BYPe19iDBHiJgFkmBD5GFdKACuUwiRMGAAoAAangTAXZzYIj9lHfgggRBiHYFIGQghFAqHUKfXQDQDBGBAKYYw5h34l0gFMVAHIki3wtssbY0kADqLpeCoCAZuLAjCIBTEsLPMo9gGBOBcHULw0jRidHCA0DIiQBADHqLEeIaiGCKPyF0IYJQJHND6DUWRgxGjGIEC0aoejxhDFMRovQwxbF%2BA6Po5RYiw7zAkJ7b2%2BdT5Bw4OSXUmdpKZ0kNsYAyBkDbDbqcThEBcCEETJHCYvBy5aAmAnJOKcM75LTtnL2HA86kD9gHIJxdS7R1jlMauiAQAzAIDEPWDdwJo3lmEAIrAFiqFCeEyJ0TYnxOWLwREKShF6BwcIUQ4hCHTJIWoAuFDSBdjIjEeefiOA%2BzKQXIJ5s9YtP1siPpYSIlRJiXEiICT9LOHRgrA8qwuDpJqbAnJydU4FPyTnEpASKlFwsNUzJccfmjN2YEgFwLsmkCAQkOwkggA

Reply via email to