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

            Bug ID: 123395
           Summary: C front end only warns (does not reject) invalid
                    pointer-to-integer initialization
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 220246428 at seu dot edu.cn
  Target Milestone: ---

I found a case where the C front end accepts code with undefined behaviour
(pointer-to-integer initialization) with only a warning, so the compiler
still produces an executable. In practice this makes it easy for users to
miss the issue, and the resulting program has unknown behaviour.

- Command line:
  gcc -std=c11 -Wall -Wextra -fsyntax-only mwe-int-from-pointer.c

Minimal reproducer
------------------
#include <stdio.h>
#include <stdint.h>
void test(void) {
    float *p = (float*)0;  /* arbitrary pointer expression */
    int64_t x = p;         /* initialize integer from pointer, no explicit cast
*/
    (void)x;
}

GCC prints only warnings such as:
mwe-int-from-pointer.c:5:16: warning: initialization of 'int64_t'
{aka 'long int'} from 'float *' makes integer from pointer without a cast
[-Wint-conversion]
    5 |     int64_t x = p;
      |                ^
Exit status is 0 and the compilation succeeds (with -fsyntax-only removed,
an executable is produced).

According to C11 6.5.16.1 ("Simple assignment") and the related constraint
rules, initializing an integer object directly from a pointer expression is
not allowed; it has undefined behaviour. The compiler is required to issue
a diagnostic for a constraint violation. GCC does issue a warning, but
because it is only a warning, the program still compiles and will run with
undefined behaviour.
I would expect at least an option in GCC to treat this case as a hard error
by default in standard modes (e.g. -std=c11), similar to how other
constraint violations are handled, so that clearly invalid code like the
example above does not silently produce an executable.

For comparison, Clang rejects the same code with an error:
error: incompatible pointer to integer conversion initializing 'int64_t'
(aka 'long') with an expression of type 'float *' [-Wint-conversion]

Reply via email to