mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 02:44:18 +08:00
c: Allow bool and enum null pointer constants [PR112556]
As reported in bug 112556, GCC wrongly rejects conversion of null pointer constants with bool or enum type to pointers in convert_for_assignment (assignment, initialization, argument passing, return). Fix the code there to allow BOOLEAN_TYPE and ENUMERAL_TYPE; it already allowed INTEGER_TYPE and BITINT_TYPE. This bug (together with -std=gnu23 meaning false has type bool rather than int) has in turn resulted in people thinking they need to fix code using false as a null pointer constant for C23 compatibility. While such a usage is certainly questionable, it has nothing to do with C23 compatibility and the right place for warnings about such usage is -Wzero-as-null-pointer-constant. I think it would be appropriate to extend -Wzero-as-null-pointer-constant to cover BOOLEAN_TYPE, ENUMERAL_TYPE and BITINT_TYPE (in all the various contexts in which that option generates warnings), though this patch doesn't do anything about that option. Bootstrapped with no regressions for x86-64-pc-linux-gnu. PR c/112556 gcc/c/ * c-typeck.cc (convert_for_assignment): Allow conversion of ENUMERAL_TYPE and BOOLEAN_TYPE null pointer constants to pointers. gcc/testsuite/ * gcc.dg/c11-null-pointer-constant-1.c, gcc.dg/c23-null-pointer-constant-1.c: New tests.
This commit is contained in:
parent
ea1506adbe
commit
3d525fce70
@ -8457,6 +8457,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
|
||||
}
|
||||
else if (codel == POINTER_TYPE
|
||||
&& (coder == INTEGER_TYPE
|
||||
|| coder == ENUMERAL_TYPE
|
||||
|| coder == BOOLEAN_TYPE
|
||||
|| coder == NULLPTR_TYPE
|
||||
|| coder == BITINT_TYPE))
|
||||
{
|
||||
|
55
gcc/testsuite/gcc.dg/c11-null-pointer-constant-1.c
Normal file
55
gcc/testsuite/gcc.dg/c11-null-pointer-constant-1.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* Test zero with different types as null pointer constant: bug 112556. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c11 -pedantic-errors -Wno-pointer-compare" } */
|
||||
|
||||
enum e { ZERO };
|
||||
|
||||
void *p1 = 0;
|
||||
void *p2 = 0LL;
|
||||
void *p3 = (char) 0;
|
||||
void *p4 = 0UL;
|
||||
void *p5 = (_Bool) 0;
|
||||
void *p6 = (enum e) ZERO;
|
||||
|
||||
void f (void *);
|
||||
|
||||
void *
|
||||
g (void)
|
||||
{
|
||||
p1 = 0;
|
||||
p2 = 0LL;
|
||||
p3 = (char) 0;
|
||||
p4 = 0UL;
|
||||
p5 = (_Bool) 0;
|
||||
p6 = (enum e) ZERO;
|
||||
f (0);
|
||||
f (0ULL);
|
||||
f (0L);
|
||||
f ((char) 0);
|
||||
f ((_Bool) 0);
|
||||
f ((enum e) ZERO);
|
||||
(1 ? p1 : 0);
|
||||
(1 ? p1 : 0L);
|
||||
(1 ? p1 : 0ULL);
|
||||
(1 ? p1 : (char) 0);
|
||||
(1 ? p1 : (_Bool) 0);
|
||||
(1 ? p1 : (enum e) 0);
|
||||
p1 == 0;
|
||||
p1 == 0LL;
|
||||
p1 == 0U;
|
||||
p1 == (char) 0;
|
||||
p1 == (_Bool) 0;
|
||||
p1 == (enum e) 0;
|
||||
p1 != 0;
|
||||
p1 != 0LL;
|
||||
p1 != 0U;
|
||||
p1 != (char) 0;
|
||||
p1 != (_Bool) 0;
|
||||
p1 != (enum e) 0;
|
||||
return 0;
|
||||
return 0UL;
|
||||
return 0LL;
|
||||
return (char) 0;
|
||||
return (_Bool) 0;
|
||||
return (enum e) 0;
|
||||
}
|
120
gcc/testsuite/gcc.dg/c23-null-pointer-constant-1.c
Normal file
120
gcc/testsuite/gcc.dg/c23-null-pointer-constant-1.c
Normal file
@ -0,0 +1,120 @@
|
||||
/* Test zero with different types as null pointer constant: bug 112556. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c23 -pedantic-errors -Wno-pointer-compare" } */
|
||||
|
||||
enum e { ZERO };
|
||||
enum e2 : bool { BZERO };
|
||||
enum e3 : long { LZERO };
|
||||
|
||||
void *p1 = 0;
|
||||
void *p2 = 0LL;
|
||||
void *p3 = (char) 0;
|
||||
void *p4 = 0UL;
|
||||
void *p5 = (bool) 0;
|
||||
void *p6 = (enum e) ZERO;
|
||||
void *p7 = false;
|
||||
void *p8 = BZERO;
|
||||
void *p9 = (enum e2) 0;
|
||||
void *p10 = LZERO;
|
||||
void *p11 = (enum e3) 0;
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
void *p12 = 0wb;
|
||||
void *p13 = 0uwb;
|
||||
#endif
|
||||
|
||||
void f (void *);
|
||||
|
||||
void *
|
||||
g (void)
|
||||
{
|
||||
p1 = 0;
|
||||
p2 = 0LL;
|
||||
p3 = (char) 0;
|
||||
p4 = 0UL;
|
||||
p5 = (bool) 0;
|
||||
p6 = (enum e) ZERO;
|
||||
p7 = false;
|
||||
p8 = BZERO;
|
||||
p9 = (enum e2) 0;
|
||||
p10 = LZERO;
|
||||
p11 = (enum e3) 0;
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
p12 = 0wb;
|
||||
p13 = 0uwb;
|
||||
#endif
|
||||
f (0);
|
||||
f (0ULL);
|
||||
f (0L);
|
||||
f ((char) 0);
|
||||
f ((bool) 0);
|
||||
f ((enum e) ZERO);
|
||||
f (false);
|
||||
f (BZERO);
|
||||
f ((enum e2) 0);
|
||||
f (LZERO);
|
||||
f ((enum e3) 0);
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
f (0wb);
|
||||
f (0uwb);
|
||||
#endif
|
||||
(1 ? p1 : 0);
|
||||
(1 ? p1 : 0L);
|
||||
(1 ? p1 : 0ULL);
|
||||
(1 ? p1 : (char) 0);
|
||||
(1 ? p1 : (bool) 0);
|
||||
(1 ? p1 : (enum e) 0);
|
||||
(1 ? p1 : false);
|
||||
(1 ? p1 : BZERO);
|
||||
(1 ? p1 : (enum e2) 0);
|
||||
(1 ? p1 : LZERO);
|
||||
(1 ? p1 : (enum e3) 0);
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
(1 ? p1 : 0wb);
|
||||
(1 ? p1 : 0uwb);
|
||||
#endif
|
||||
p1 == 0;
|
||||
p1 == 0LL;
|
||||
p1 == 0U;
|
||||
p1 == (char) 0;
|
||||
p1 == (bool) 0;
|
||||
p1 == (enum e) 0;
|
||||
p1 == false;
|
||||
p1 == BZERO;
|
||||
p1 == (enum e2) 0;
|
||||
p1 == LZERO;
|
||||
p1 == (enum e3) 0;
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
p1 == 0wb;
|
||||
p1 == 0uwb;
|
||||
#endif
|
||||
p1 != 0;
|
||||
p1 != 0LL;
|
||||
p1 != 0U;
|
||||
p1 != (char) 0;
|
||||
p1 != (bool) 0;
|
||||
p1 != (enum e) 0;
|
||||
p1 != false;
|
||||
p1 != BZERO;
|
||||
p1 != (enum e2) 0;
|
||||
p1 != LZERO;
|
||||
p1 != (enum e3) 0;
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
p1 != 0wb;
|
||||
p1 != 0uwb;
|
||||
#endif
|
||||
return 0;
|
||||
return 0UL;
|
||||
return 0LL;
|
||||
return (char) 0;
|
||||
return (bool) 0;
|
||||
return (enum e) 0;
|
||||
return false;
|
||||
return BZERO;
|
||||
return (enum e2) 0;
|
||||
return LZERO;
|
||||
return (enum e3) 0;
|
||||
#ifdef __BITINT_MAXWIDTH__
|
||||
return 0wb;
|
||||
return 0uwb;
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue
Block a user