diff mbox

[C] Clamp down "incomplete type" error (PR c/63543)

Message ID 20141016172030.GM10501@redhat.com
State New
Headers show

Commit Message

Marek Polacek Oct. 16, 2014, 5:20 p.m. UTC
On Wed, Oct 15, 2014 at 09:46:20PM +0000, Joseph S. Myers wrote:
> On Wed, 15 Oct 2014, Marek Polacek wrote:
> 
> > We've got a complaint that the "dereferencing pointer to incomplete
> > type" error is printed for all occurrences of the incomplete type,
> > which is too verbose.  Also it'd be nicer to print the type as well.
> > This patch fixes this; if we find an incomplete type, mark it with error
> > node, then we don't print the error message more than once.
> 
> I don't like this approach of modifying the type; type nodes are shared 
> objects and this could affect all sorts of other logic subsequently 
> working with the type.  I think there should be some sort of annotation of 
> the type (either in the type itself, or on the side) that *only* means an 
> error has been given for the type being incomplete, rather than inserting 
> error_mark_node into the type.

I'm sorry.  Here is another version, which uses a lang flag to distinguish
whether a "dereferencing incomplete..." error message has been given.

One could argue that I should've named the lang flag e.g.
C_TYPE_INCOMPLETE_ERROR_REPORTED, but I hope it can be reused in the
future for some similar purpose.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-10-16  Marek Polacek  <polacek@redhat.com>

	PR c/63543
	* c-tree.h (C_TYPE_ERROR_REPORTED): Define.
	* c-typeck.c (build_indirect_ref): Don't print the "dereferencing..."
	error multiple times.  Print the type.

	* gcc.dg/pr63543.c: New test.
	* gcc.dg/array-8.c: Remove dg-error.
	* gcc.dg/pr48552-1.c: Remove and adjust dg-error.
	* gcc.dg/pr48552-2.c: Likewise.


	Marek

Comments

Jeff Law Oct. 16, 2014, 10:08 p.m. UTC | #1
On 10/16/14 11:20, Marek Polacek wrote:
> On Wed, Oct 15, 2014 at 09:46:20PM +0000, Joseph S. Myers wrote:
>> On Wed, 15 Oct 2014, Marek Polacek wrote:
>>
>>> We've got a complaint that the "dereferencing pointer to incomplete
>>> type" error is printed for all occurrences of the incomplete type,
>>> which is too verbose.  Also it'd be nicer to print the type as well.
>>> This patch fixes this; if we find an incomplete type, mark it with error
>>> node, then we don't print the error message more than once.
>>
>> I don't like this approach of modifying the type; type nodes are shared
>> objects and this could affect all sorts of other logic subsequently
>> working with the type.  I think there should be some sort of annotation of
>> the type (either in the type itself, or on the side) that *only* means an
>> error has been given for the type being incomplete, rather than inserting
>> error_mark_node into the type.
>
> I'm sorry.  Here is another version, which uses a lang flag to distinguish
> whether a "dereferencing incomplete..." error message has been given.
>
> One could argue that I should've named the lang flag e.g.
> C_TYPE_INCOMPLETE_ERROR_REPORTED, but I hope it can be reused in the
> future for some similar purpose.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2014-10-16  Marek Polacek  <polacek@redhat.com>
>
> 	PR c/63543
> 	* c-tree.h (C_TYPE_ERROR_REPORTED): Define.
> 	* c-typeck.c (build_indirect_ref): Don't print the "dereferencing..."
> 	error multiple times.  Print the type.
>
> 	* gcc.dg/pr63543.c: New test.
> 	* gcc.dg/array-8.c: Remove dg-error.
> 	* gcc.dg/pr48552-1.c: Remove and adjust dg-error.
> 	* gcc.dg/pr48552-2.c: Likewise.
OK.

It's probably safe to assume we'll find more uses for that flag.

jeff
diff mbox

Patch

diff --git gcc/c/c-tree.h gcc/c/c-tree.h
index e6aca01..5ff9d9c 100644
--- gcc/c/c-tree.h
+++ gcc/c/c-tree.h
@@ -56,6 +56,9 @@  along with GCC; see the file COPYING3.  If not see
    This is used for -Wc++-compat. */
 #define C_TYPE_DEFINED_IN_STRUCT(TYPE) TYPE_LANG_FLAG_2 (TYPE)
 
+/* Record whether an "incomplete type" error was given for the type.  */
+#define C_TYPE_ERROR_REPORTED(TYPE) TYPE_LANG_FLAG_3 (TYPE)
+
 /* Record whether a typedef for type `int' was actually `signed int'.  */
 #define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
 
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 5c0697a..0f363f5 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -2378,7 +2378,12 @@  build_indirect_ref (location_t loc, tree ptr, ref_operator errstring)
 
 	  if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
 	    {
-	      error_at (loc, "dereferencing pointer to incomplete type");
+	      if (!C_TYPE_ERROR_REPORTED (TREE_TYPE (ptr)))
+		{
+		  error_at (loc, "dereferencing pointer to incomplete type "
+			    "%qT", t);
+		  C_TYPE_ERROR_REPORTED (TREE_TYPE (ptr)) = 1;
+		}
 	      return error_mark_node;
 	    }
 	  if (VOID_TYPE_P (t) && c_inhibit_evaluation_warnings == 0)
diff --git gcc/testsuite/gcc.dg/array-8.c gcc/testsuite/gcc.dg/array-8.c
index d469a80..2872985 100644
--- gcc/testsuite/gcc.dg/array-8.c
+++ gcc/testsuite/gcc.dg/array-8.c
@@ -45,5 +45,4 @@  g (void)
   sip[0]; /* { dg-error "invalid use of undefined type 'struct si'" } */
   /* { dg-error "dereferencing pointer to incomplete type" "incomplete" { target *-*-* } 45 } */
   0[sip]; /* { dg-error "invalid use of undefined type 'struct si'" } */
-  /* { dg-error "dereferencing pointer to incomplete type" "incomplete" { target *-*-* } 47 } */
 }
diff --git gcc/testsuite/gcc.dg/pr48552-1.c gcc/testsuite/gcc.dg/pr48552-1.c
index 877c4c2..4b833fb 100644
--- gcc/testsuite/gcc.dg/pr48552-1.c
+++ gcc/testsuite/gcc.dg/pr48552-1.c
@@ -49,5 +49,5 @@  f7 (struct S *x)
 void
 f8 (struct S *x)
 {
-  __asm volatile ("" : "=r" (*x));	/* { dg-error "dereferencing pointer to incomplete type" "incomplete" } */
-}					/* { dg-error "invalid lvalue in asm output 0" "invalid lvalue" { target *-*-* } 52 } */
+  __asm volatile ("" : "=r" (*x));	/* { dg-error "invalid lvalue in asm output 0" } */
+}
diff --git gcc/testsuite/gcc.dg/pr48552-2.c gcc/testsuite/gcc.dg/pr48552-2.c
index a796983..954c411 100644
--- gcc/testsuite/gcc.dg/pr48552-2.c
+++ gcc/testsuite/gcc.dg/pr48552-2.c
@@ -49,5 +49,5 @@  f7 (struct S *x)
 void
 f8 (struct S *x)
 {
-  __asm ("" : "=r" (*x));	/* { dg-error "dereferencing pointer to incomplete type" "incomplete" } */
-}				/* { dg-error "invalid lvalue in asm output 0" "invalid lvalue" { target *-*-* } 52 } */
+  __asm ("" : "=r" (*x));	/* { dg-error "invalid lvalue in asm output 0" } */
+}
diff --git gcc/testsuite/gcc.dg/pr63543.c gcc/testsuite/gcc.dg/pr63543.c
index e69de29..215b62e 100644
--- gcc/testsuite/gcc.dg/pr63543.c
+++ gcc/testsuite/gcc.dg/pr63543.c
@@ -0,0 +1,21 @@ 
+/* PR c/63543 */
+/* { dg-do compile } */
+
+struct S;
+union U;
+
+int
+f1 (struct S *s)
+{
+  return s->a /* { dg-error "dereferencing pointer to incomplete type .struct S." } */
+	 + s->b
+	 + s->c;
+}
+
+int
+f2 (union U *u)
+{
+  return u->a /* { dg-error "dereferencing pointer to incomplete type .union U." } */
+	 + u->a
+	 + u->a;
+}