diff mbox series

c: Allow comparison of pointers to complete and incomplete types for C11 [PR95630]

Message ID alpine.DEB.2.22.394.2011232329160.321778@digraph.polyomino.org.uk
State New
Headers show
Series c: Allow comparison of pointers to complete and incomplete types for C11 [PR95630] | expand

Commit Message

Joseph Myers Nov. 23, 2020, 11:29 p.m. UTC
As noted in bug 95630, C11 removed a restriction in C99 on comparing
pointers to compatible complete and incomplete types (this was one of
the changes in N1439, which was largely a terminological change to
make incomplete types a subset of object types rather than a different
kind of type).  Implement that change by using pedwarn_c99 with
OPT_Wpedantic for this diagnostic.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Applied to 
mainline.

gcc/c/
2020-11-23  Joseph Myers  <joseph@codesourcery.com>

	PR c/95630
	* c-typeck.c (build_binary_op): Use pedwarn_c99 with OPT_Wpedantic
	for comparisons of complete and incomplete pointers.

gcc/testsuite/
2020-11-23  Joseph Myers  <joseph@codesourcery.com>

	PR c/95630
	* gcc.dg/c11-compare-incomplete-1.c,
	gcc.dg/c11-compare-incomplete-2.c,
	gcc.dg/c99-compare-incomplete-1.c,
	gcc.dg/c99-compare-incomplete-2.c: New tests.
diff mbox series

Patch

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 286f3d9cd6c..cdc491a25fd 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -12266,8 +12266,8 @@  build_binary_op (location_t location, enum tree_code code,
 	      result_type = common_pointer_type (type0, type1);
 	      if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
 		  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
-		pedwarn (location, 0,
-			 "comparison of complete and incomplete pointers");
+		pedwarn_c99 (location, OPT_Wpedantic,
+			     "comparison of complete and incomplete pointers");
 	      else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
 		pedwarn (location, OPT_Wpedantic, "ISO C forbids "
 			 "ordered comparisons of pointers to functions");
diff --git a/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c b/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c
new file mode 100644
index 00000000000..b1c05cf221e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c
@@ -0,0 +1,52 @@ 
+/* Test comparisons of pointers to complete and incomplete types are
+   accepted in C11 mode.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+  return p < q;
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+  return p <= q;
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+  return p > q;
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+  return p >= q;
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+  return q < p;
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+  return q <= p;
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+  return q > p;
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+  return q >= p;
+}
diff --git a/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c b/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c
new file mode 100644
index 00000000000..8e809e87e9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c
@@ -0,0 +1,52 @@ 
+/* Test comparisons of pointers to complete and incomplete types are
+   diagnosed in C11 mode with -Wc99-c11-compat.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors -Wc99-c11-compat" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+  return p < q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+  return p <= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+  return p > q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+  return p >= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+  return q < p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+  return q <= p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+  return q > p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+  return q >= p; /* { dg-warning "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c b/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c
new file mode 100644
index 00000000000..dfafc39145e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c
@@ -0,0 +1,52 @@ 
+/* Test comparisons of pointers to complete and incomplete types are
+   diagnosed in C99 mode: -pedantic.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+  return p < q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+  return p <= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+  return p > q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+  return p >= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+  return q < p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+  return q <= p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+  return q > p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+  return q >= p; /* { dg-warning "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c b/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c
new file mode 100644
index 00000000000..5ae7f303e07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c
@@ -0,0 +1,52 @@ 
+/* Test comparisons of pointers to complete and incomplete types are
+   diagnosed in C99 mode: -pedantic-errors.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+  return p < q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+  return p <= q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+  return p > q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+  return p >= q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+  return q < p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+  return q <= p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+  return q > p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+  return q >= p; /* { dg-error "complete and incomplete" } */
+}