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

            Bug ID: 93873
           Summary: gcc or lto-wrapper does not consider individual
                    bitfield values on static analysis and instead tests
                    the whole value of all bitfield bits combined
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: emil.fihlman at aalto dot fi
  Target Milestone: ---

On gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)

Given these two files (and stdtypes.h being available from
https://emil.fi/d/stdtypes.h but it's basically just include stdint.h and
typedef u?int\d+_t to the correct [su]\d+

$cat ltobuglib.h
#include <stdtypes.h>
#include <stdlib.h>
#include <unistd.h>

struct thing
{
        u64 v;
        struct
        {
                u64 dox:1;
                u64 freeme:1;
        } flags;
};

struct thing *makeit(struct thing *t)
{
        u8 dynamic=!t;
        if(dynamic)
        {
                t=calloc(1, sizeof(*t));
                if(!t)
                {
                        return(NULL);
                }
        }
        t->v=0;
        t->flags.dox=1;
        t->flags.freeme=dynamic;
        return(t);
}

void freeit(struct thing *t)
{
        if(t->flags.freeme)
        {
                free(t);
        }
}



$cat ltobug.c
#include <stdtypes.h>
#include <stdio.h>
#include "ltobuglib.h"

s32 main(void)
{
        struct thing t={0};
        if(!makeit(&t))
        {
                return(-1);
        }
        printf("%lu %u %u\n", t.v, t.flags.dox, t.flags.freeme);
        freeit(&t);
        return(0);
}



$gcc -Wall -Werror -Wextra -O3 -flto -o ltobug ltobug.c



produces



In function ‘freeit’,
    inlined from ‘main’ at ltobug.c:13:2:
ltobuglib.h:36:3: error: attempt to free a non-heap object ‘t’
[-Werror=free-nonheap-object]
   free(t);
   ^
lto1: all warnings being treated as errors
lto-wrapper: fatal error: gcc returned 1 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status



but changing t->flags.dox=1 to 0 compiles cleanly.
Without -flto (and dox set to 1) the result is



In file included from ltobug.c:3:0:
In function ‘freeit’,
    inlined from ‘main’ at ltobug.c:13:2:
ltobuglib.h:36:3: error: attempt to free a non-heap object ‘t’
[-Werror=free-nonheap-object]
   free(t);
   ^~~~~~~
cc1: all warnings being treated as errors



On a different project of mine, the code cleanly compiles without -flto (but
fails with -flto as above) but here gcc seems to do the same issue without
-flto, too.

Reply via email to