Skip to content

Commit

Permalink
c: Turn -Wincompatible-pointer-types into a permerror
Browse files Browse the repository at this point in the history
The change to build_conditional_expr drops the downgrade
from a pedwarn to warning for builtins for C99 and later
language dialects.  It remains a warning in C89 mode (not
a permerror), as the -std=gnu89 -fno-permissive test shows.

gcc/

	* doc/invoke.texi (Warning Options): Document changes.

gcc/c/

	PR c/96284
	* c-typeck.cc (build_conditional_expr): Upgrade most pointer
	type mismatches to a permerror.
	(convert_for_assignment): Use permerror_opt and
	permerror_init for OPT_Wincompatible_pointer_types warnings.

gcc/testsuite/

	* gcc.dg/permerror-default.c (incompatible_pointer_types):
	Expect new permerror.
	* gcc.dg/permerror-gnu89-nopermissive.c
	(incompatible_pointer_types): Likewise.
	* gcc.dg/permerror-pedantic.c (incompatible_pointer_types):
	Likewise.
	* gcc.dg/permerror-system.c: Likewise.
	* gcc.dg/Wincompatible-pointer-types-2.c: Compile with
	-fpermissive due to expected errors.
	* gcc.dg/Wincompatible-pointer-types-5.c: New test.  Copied
	from gcc.dg/Wincompatible-pointer-types-2.c.  Expect errors.
	* gcc.dg/anon-struct-11.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/anon-struct-11a.c: New test.  Copied from
	gcc.dg/anon-struct-11.c.  Expect errors.
	* gcc.dg/anon-struct-13.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/anon-struct-13a.c: New test.  Copied from
	gcc.dg/anon-struct-13.c.  Expect errors.
	* gcc.dg/builtin-arith-overflow-4.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/builtin-arith-overflow-4a.c: New test.  Copied from
	gcc.dg/builtin-arith-overflow-4.c.  Expect errors.
	* gcc.dg/c23-qual-4.c: Expect -Wincompatible-pointer-types errors.
	* gcc.dg/dfp/composite-type.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/dfp/composite-type-2.c: New test.  Copied from
	gcc.dg/dfp/composite-type.c.  Expect errors.
	* gcc.dg/diag-aka-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/diag-aka-1a.c: New test.  Copied from
	gcc.dg/diag-aka-1a.c.  Expect errors.
	* gcc.dg/enum-compat-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/enum-compat-2.c: New test.  Copied from
	gcc.dg/enum-compat-1.c.  Expect errors.
	* gcc.dg/func-ptr-conv-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/func-ptr-conv-2.c: New test.  Copied from
	gcc.dg/func-ptr-conv-1.c.  Expect errors.
	* gcc.dg/init-bad-7.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/init-bad-7a.c: New test.  Copied from gcc.dg/init-bad-7.c.
	Expect errors.
	* gcc.dg/noncompile/incomplete-3.c (foo): Expect
	-Wincompatible-pointer-types error.
	* gcc.dg/param-type-mismatch-2.c (test8): Likewise.
	* gcc.dg/pointer-array-atomic.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/pointer-array-atomic-2.c: New test.  Copied from
	gcc.dg/pointer-array-atomic.c.  Expect errors.
	* gcc.dg/pointer-array-quals-1.c (test): Expect
	-Wincompatible-pointer-types errors.
	* gcc.dg/transparent-union-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/transparent-union-1a.c: New test.  Copied from
	gcc.dg/transparent-union-1.c.  Expect errors.
	* gcc.target/aarch64/acle/memtag_2a.c
	(test_memtag_warning_return_qualifier): Expect additional
	errors.
	* gcc.target/aarch64/sve/acle/general-c/load_2.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_2.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_3.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_4.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_5.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_2.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_3.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_4.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/sizeless-1.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/sizeless-2.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_1.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_2.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general/attributes_7.c
	(f1): Likewise.
	* gcc.target/i386/sse2-bfloat16-scalar-typecheck.c (footest):
	Expect -Wincompatible-pointer-types errors.
	* gcc.target/i386/vect-bfloat16-typecheck_1.c (footest): Likewise.
	* gcc.target/i386/vect-bfloat16-typecheck_2.c (footest): Likewise.
  • Loading branch information
fweimer-rh committed Dec 1, 2023
1 parent 4ecfa6c commit 9715c54
Show file tree
Hide file tree
Showing 55 changed files with 726 additions and 130 deletions.
62 changes: 35 additions & 27 deletions gcc/c/c-typeck.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5463,8 +5463,15 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
else
{
int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
if (emit_diagnostic (bltin1 && bltin2 ? DK_WARNING : DK_PEDWARN,
colon_loc, OPT_Wincompatible_pointer_types,
diagnostic_t kind = DK_PERMERROR;
if (!flag_isoc99)
/* This downgrade to a warning ensures that -std=gnu89
-pedantic-errors does not flag these mismatches between
builtins as errors (as DK_PERMERROR would). ISO C99
and later do not have implicit function declarations,
so the mismatch cannot occur naturally there. */
kind = bltin1 && bltin2 ? DK_WARNING : DK_PEDWARN;
if (emit_diagnostic (kind, colon_loc, OPT_Wincompatible_pointer_types,
"pointer type mismatch "
"in conditional expression"))
{
Expand Down Expand Up @@ -7602,46 +7609,47 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
auto_diagnostic_group d;
range_label_for_type_mismatch rhs_label (rhstype, type);
gcc_rich_location richloc (expr_loc, &rhs_label);
if (pedwarn (&richloc, OPT_Wincompatible_pointer_types,
"passing argument %d of %qE from incompatible "
"pointer type", parmnum, rname))
if (permerror_opt (&richloc, OPT_Wincompatible_pointer_types,
"passing argument %d of %qE from "
"incompatible pointer type",
parmnum, rname))
inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
}
break;
case ic_assign:
if (bltin)
pedwarn (location, OPT_Wincompatible_pointer_types,
"assignment to %qT from pointer to "
"%qD with incompatible type %qT",
type, bltin, rhstype);
permerror_opt (location, OPT_Wincompatible_pointer_types,
"assignment to %qT from pointer to "
"%qD with incompatible type %qT",
type, bltin, rhstype);
else
pedwarn (location, OPT_Wincompatible_pointer_types,
"assignment to %qT from incompatible pointer type %qT",
type, rhstype);
permerror_opt (location, OPT_Wincompatible_pointer_types,
"assignment to %qT from incompatible pointer "
"type %qT", type, rhstype);
break;
case ic_init:
case ic_init_const:
if (bltin)
pedwarn_init (location, OPT_Wincompatible_pointer_types,
"initialization of %qT from pointer to "
"%qD with incompatible type %qT",
type, bltin, rhstype);
permerror_init (location, OPT_Wincompatible_pointer_types,
"initialization of %qT from pointer to "
"%qD with incompatible type %qT",
type, bltin, rhstype);
else
pedwarn_init (location, OPT_Wincompatible_pointer_types,
"initialization of %qT from incompatible "
"pointer type %qT",
type, rhstype);
permerror_init (location, OPT_Wincompatible_pointer_types,
"initialization of %qT from incompatible "
"pointer type %qT",
type, rhstype);
break;
case ic_return:
if (bltin)
pedwarn (location, OPT_Wincompatible_pointer_types,
"returning pointer to %qD of type %qT from "
"a function with incompatible type %qT",
bltin, rhstype, type);
permerror_opt (location, OPT_Wincompatible_pointer_types,
"returning pointer to %qD of type %qT from "
"a function with incompatible type %qT",
bltin, rhstype, type);
else
pedwarn (location, OPT_Wincompatible_pointer_types,
"returning %qT from a function with incompatible "
"return type %qT", rhstype, type);
permerror_opt (location, OPT_Wincompatible_pointer_types,
"returning %qT from a function with "
"incompatible return type %qT", rhstype, type);
break;
default:
gcc_unreachable ();
Expand Down
6 changes: 6 additions & 0 deletions gcc/doc/invoke.texi
Original file line number Diff line number Diff line change
Expand Up @@ -6186,6 +6186,7 @@ that have their own flag:
@gccoptlist{
-Wimplicit-function-declaration @r{(C and Objective-C only)}
-Wimplicit-int @r{(C and Objective-C only)}
-Wincompatible-pointer-types @r{(C and Objective-C only)}
-Wint-conversion @r{(C and Objective-C only)}
-Wnarrowing @r{(C++)}
-Wreturn-mismatch @r{(C and Objective-C only)}
Expand Down Expand Up @@ -8566,6 +8567,11 @@ types. This warning is for cases not covered by @option{-Wno-pointer-sign},
which warns for pointer argument passing or assignment with different
signedness.

By default, in C99 and later dialects of C, GCC treats this issue as an
error. The error can be downgraded to a warning using
@option{-fpermissive} (along with certain other errors), or for this
error alone, with @option{-Wno-error=incompatible-pointer-types}.

This warning is upgraded to an error by @option{-pedantic-errors}.

@opindex Wno-int-conversion
Expand Down
2 changes: 1 addition & 1 deletion gcc/testsuite/gcc.dg/Wincompatible-pointer-types-2.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "" } */
/* { dg-options "-fpermissive" } */

void *
f1 (int flag, int *a, long *b)
Expand Down
10 changes: 10 additions & 0 deletions gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* { dg-do compile } */
/* { dg-options "" } */

void *
f1 (int flag, int *a, long *b)
{
return flag ? a : b; /* { dg-error "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
/* { dg-note "first expression has type 'int \\*'" "" { target *-*-* } .-1 } */
/* { dg-note "second expression has type 'long int \\*'" "" { target *-*-* } .-2 } */
}
5 changes: 2 additions & 3 deletions gcc/testsuite/gcc.dg/anon-struct-11.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* { dg-do compile } */

/* No special options--in particular, turn off the default
-pedantic-errors option. */
/* { dg-options "" } */
/* Also turn off the default -pedantic-errors option. */
/* { dg-options "-fpermissive" } */

/* When not using -fplan9-extensions, we don't support automatic
conversion of pointer types, and we don't support referring to a
Expand Down
111 changes: 111 additions & 0 deletions gcc/testsuite/gcc.dg/anon-struct-11a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* { dg-do compile } */

/* No special options--in particular, turn off the default
-pedantic-errors option. */
/* { dg-options "" } */

/* When not using -fplan9-extensions, we don't support automatic
conversion of pointer types, and we don't support referring to a
typedef name directly. */

extern void exit (int);
extern void abort (void);

struct A { char a; };

struct B {
char b;
struct A; /* { dg-warning "does not declare anything" } */
char c;
};

void
f1 (struct A *p) /* { dg-message "expected" } */
{
p->a = 1;
}

void
test1 (void)
{
struct B b;
struct A *p;

b.b = 2;
b.c = 3;
f1 (&b); /* { dg-error "incompatible pointer type" } */
if (b.a != 1) /* { dg-error "no member" } */
abort ();
if (b.b != 2 || b.c != 3)
abort ();
p = &b; /* { dg-error "incompatible pointer type" } */
if (p->a != 1)
abort ();
}

typedef struct { char d; } D;

struct E {
char b;
struct F { char f; }; /* { dg-warning "does not declare anything" } */
char c;
union {
D; /* { dg-warning "does not declare anything" } */
};
char e;
};

void
f2 (struct F *p) /* { dg-message "expected" } */
{
p->f = 6;
}

void
f3 (D *p) /* { dg-message "expected" } */
{
p->d = 4;
}

void
f4 (D d)
{
}

void
test2 (void)
{
struct E e;
struct F *pf;
D *pd;
D d;

e.b = 2;
e.c = 3;
e.e = 5;
f2 (&e); /* { dg-error "incompatible pointer type" } */
f3 (&e); /* { dg-error "incompatible pointer type" } */
if (e.d != 4) /* { dg-error "no member" } */
abort ();
if (e.f != 6) /* { dg-error "no member" } */
abort ();
if (e.b != 2 || e.c != 3 || e.e != 5)
abort ();
pf = &e; /* { dg-error "incompatible pointer type" } */
if (pf->f != 6)
abort ();
pd = &e; /* { dg-error "incompatible pointer type" } */
if (pd->d != 4)
abort ();
d = e.D; /* { dg-error "no member" } */
f3 (&e.D); /* { dg-error "no member" } */
f4 (e.D); /* { dg-error "no member" } */
}

int
main ()
{
test1 ();
test2 ();
exit (0);
}
2 changes: 1 addition & 1 deletion gcc/testsuite/gcc.dg/anon-struct-13.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-options "-fplan9-extensions" } */
/* { dg-options "-fpermissive -fplan9-extensions" } */

/* Test for ambiguity when using the Plan 9 extensions. */

Expand Down
76 changes: 76 additions & 0 deletions gcc/testsuite/gcc.dg/anon-struct-13a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* { dg-do compile } */
/* { dg-options "-fplan9-extensions" } */

/* Test for ambiguity when using the Plan 9 extensions. */

struct A {
char a; /* { dg-error "duplicate member" } */
};

struct B
{
struct A;
struct A;
};

char
f1 (struct B *p)
{
return p->a; /* { dg-error "no member" } */
}

void
f2 (struct A *p) /* { dg-message "expected" } */
{
}

void
f3 (struct B *p)
{
f2 (p); /* { dg-error "incompatible pointer type" } */
}

struct C
{
char c; /* { dg-error "duplicate member" } */
};

struct D
{
struct C;
};

struct E
{
struct C;
struct D;
};

char
f4 (struct E *p)
{
return p->c; /* { dg-error "no member" } */
}

void
f6 (struct C *p) /* { dg-message "expected" } */
{
}

void
f7 (struct E *p)
{
f6 (p); /* { dg-error "incompatible pointer type" } */
}

struct A
f8 (struct B *p)
{
return p->A; /* { dg-error "no member" } */
}

struct C
f9 (struct E *p)
{
return p->C; /* { dg-error "no member" } */
}
2 changes: 1 addition & 1 deletion gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* PR c/90628 */
/* { dg-do compile } */
/* { dg-options "" } */
/* { dg-options "-fpermissive" } */

_Atomic int a = 1, b = 2, c = 3;
_Atomic long d = 4, e = 5, f = 6;
Expand Down
43 changes: 43 additions & 0 deletions gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* PR c/90628 */
/* { dg-do compile } */
/* { dg-options "" } */

_Atomic int a = 1, b = 2, c = 3;
_Atomic long d = 4, e = 5, f = 6;
_Atomic long long g = 7, h = 8, i = 9;

void
f1 ()
{
__builtin_add_overflow (a, b, &c); /* { dg-error "argument 3 in call to function '__builtin_add_overflow' has pointer to '_Atomic' type" } */
}

void
f2 ()
{
__builtin_sub_overflow (d, e, &f); /* { dg-error "argument 3 in call to function '__builtin_sub_overflow' has pointer to '_Atomic' type" } */
}

void
f3 ()
{
__builtin_mul_overflow (g, h, &i); /* { dg-error "argument 3 in call to function '__builtin_mul_overflow' has pointer to '_Atomic' type" } */
}

void
f4 ()
{
__builtin_sadd_overflow (a, b, &c); /* { dg-error "passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type" } */
}

void
f5 ()
{
__builtin_ssubl_overflow (d, e, &f); /* { dg-error "passing argument 3 of '__builtin_ssubl_overflow' from incompatible pointer type" } */
}

void
f6 ()
{
__builtin_smulll_overflow (g, h, &i); /* { dg-error "passing argument 3 of '__builtin_smulll_overflow' from incompatible pointer type" } */
}

0 comments on commit 9715c54

Please sign in to comment.