===================================================================
@@ -55,9 +55,6 @@ 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)
===================================================================
@@ -2054,6 +2054,8 @@ convert_lvalue_to_rvalue (location_t loc, struct c
mark_exp_read (exp.value);
if (convert_p)
exp = default_function_array_conversion (loc, exp);
+ if (!VOID_TYPE_P (TREE_TYPE (exp.value)))
+ exp.value = require_complete_type (loc, exp.value);
if (really_atomic_lvalue (exp.value))
{
vec<tree, va_gc> *params;
@@ -2550,16 +2552,6 @@ build_indirect_ref (location_t loc, tree ptr, ref_
ref = build1 (INDIRECT_REF, t, pointer);
- if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_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)
warning_at (loc, 0, "dereferencing %<void *%> pointer");
===================================================================
@@ -43,6 +43,5 @@ g (void)
pv[0]; /* { dg-warning "dereferencing 'void \\*' pointer" } */
0[pv]; /* { dg-warning "dereferencing 'void \\*' pointer" } */
sip[0]; /* { dg-error "invalid use of undefined type 'struct si'" } */
- /* { dg-error "dereferencing pointer to incomplete type" "incomplete" { target *-*-* } .-1 } */
0[sip]; /* { dg-error "invalid use of undefined type 'struct si'" } */
}
===================================================================
@@ -13,14 +13,16 @@ f0 (int i)
{
ve; /* { dg-error "incomplete" } */
vs; /* { dg-error "incomplete" } */
- (void) ve;
- (void) vs;
+ (void) ve; /* { dg-error "incomplete" } */
+ (void) vs; /* { dg-error "incomplete" } */
(void) (i ? ve : ve); /* { dg-error "incomplete" } */
(void) (i ? vs : vs); /* { dg-error "incomplete" } */
(void) (ve = ve); /* { dg-error "incomplete" } */
(void) (vs = vs); /* { dg-error "incomplete" } */
- (void) ve, (void) ve;
- (void) vs, (void) vs;
+ (void) ve, /* { dg-error "incomplete" } */
+ (void) ve; /* { dg-error "incomplete" } */
+ (void) vs, /* { dg-error "incomplete" } */
+ (void) vs; /* { dg-error "incomplete" } */
p = &ve;
p = &vs;
(void) sizeof (ve); /* { dg-error "incomplete" } */
===================================================================
@@ -4,17 +4,17 @@
enum E e; /* { dg-error "storage size" } */
-void bar (int [e]); /* { dg-error "size of unnamed array has incomplete type" } */
-void bar2 (int [][e]); /* { dg-error "size of unnamed array has incomplete type" } */
+void bar (int [e]); /* { dg-error "has an incomplete type" } */
+void bar2 (int [][e]); /* { dg-error "has an incomplete type" } */
void
foo (void)
{
- int a1[e]; /* { dg-error "size of array .a1. has incomplete type" } */
- int a2[e][3]; /* { dg-error "size of array .a2. has incomplete type" } */
+ int a1[e]; /* { dg-error "has an incomplete type" } */
+ int a2[e][3]; /* { dg-error "has an incomplete type" } */
struct S
{
- int a3[e]; /* { dg-error "size of array .a3. has incomplete type" } */
+ int a3[e]; /* { dg-error "has an incomplete type" } */
};
}
===================================================================
@@ -0,0 +1,22 @@
+/* Test handling of lvalues of incomplete types. Bugs 36941, 88647
+ (invalid), 88827. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+struct S;
+
+extern struct S var;
+extern struct S *vp;
+
+void
+f8 (void)
+{
+ /* These are valid because there is no constraint violation and the
+ result of '*' is never converted from an lvalue to an rvalue
+ (which would yield undefined behavior). */
+ &var;
+ &*vp;
+ &(var);
+ &(*vp);
+ &*&*vp;
+}
===================================================================
@@ -0,0 +1,77 @@
+/* Test handling of lvalues of incomplete types. Bugs 36941, 88647
+ (invalid), 88827. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+struct S;
+
+extern struct S var;
+extern struct S *vp;
+extern int i;
+
+void
+f1 (void)
+{
+ var; /* { dg-error "has an incomplete type" } */
+ var, (void) 0; /* { dg-error "has an incomplete type" } */
+ (i
+ ? var /* { dg-error "has an incomplete type" } */
+ : var); /* { dg-error "has an incomplete type" } */
+}
+
+void
+f2 (void)
+{
+ (void) var; /* { dg-error "has an incomplete type" } */
+ (void) (var, (void) 0); /* { dg-error "has an incomplete type" } */
+ (void) (i
+ ? var /* { dg-error "has an incomplete type" } */
+ : var); /* { dg-error "has an incomplete type" } */
+}
+
+void
+f3 (void)
+{
+ (const void) var; /* { dg-error "has an incomplete type" } */
+ (const void) (var, (void) 0); /* { dg-error "has an incomplete type" } */
+ (const void) (i
+ ? var /* { dg-error "has an incomplete type" } */
+ : var); /* { dg-error "has an incomplete type" } */
+}
+
+void
+f4 (void)
+{
+ *vp; /* { dg-error "invalid use of undefined type" } */
+ *vp, (void) 0; /* { dg-error "invalid use of undefined type" } */
+ (i
+ ? *vp /* { dg-error "invalid use of undefined type" } */
+ : *vp); /* { dg-error "invalid use of undefined type" } */
+}
+
+void
+f5 (void)
+{
+ (void) *vp; /* { dg-error "invalid use of undefined type" } */
+ (void) (*vp, (void) 0); /* { dg-error "invalid use of undefined type" } */
+ (void) (i
+ ? *vp /* { dg-error "invalid use of undefined type" } */
+ : *vp); /* { dg-error "invalid use of undefined type" } */
+}
+
+void
+f6 (void)
+{
+ (const void) *vp; /* { dg-error "invalid use of undefined type" } */
+ (const void) (*vp, (void) 0); /* { dg-error "invalid use of undefined type" } */
+ (const void) (i
+ ? *vp /* { dg-error "invalid use of undefined type" } */
+ : *vp); /* { dg-error "invalid use of undefined type" } */
+}
+
+void
+f7 (void)
+{
+ /* This is invalid because of the constraints on []. */
+ &vp[0]; /* { dg-error "invalid use of undefined type" } */
+}
===================================================================
@@ -5,5 +5,5 @@ int foo (void)
{
b_t d;
struct b_t *c = &d; /* { dg-warning "incompatible pointer type" } */
- c->a; /* { dg-error "incomplete type" } */
+ c->a; /* { dg-error "invalid use of undefined type" } */
}
===================================================================
@@ -43,11 +43,12 @@ f6 (void *x)
void
f7 (struct S *x)
{
- __asm volatile ("" : : "r" (*x)); /* { dg-error "dereferencing pointer to incomplete type" } */
+ __asm volatile ("" : : "r" (*x)); /* { dg-error "invalid use of undefined type" } */
}
void
f8 (struct S *x)
{
- __asm volatile ("" : "=r" (*x)); /* { dg-error "invalid lvalue in 'asm' output 0" } */
+ __asm volatile ("" : "=r" (*x)); /* { dg-error "impossible constraint in 'asm'" } */
+ /* { dg-error "non-memory output 0 must stay in memory" "memory" { target *-*-* } .-1 } */
}
===================================================================
@@ -43,11 +43,12 @@ f6 (void *x)
void
f7 (struct S *x)
{
- __asm ("" : : "r" (*x)); /* { dg-error "dereferencing pointer to incomplete type" } */
+ __asm ("" : : "r" (*x)); /* { dg-error "invalid use of undefined type" } */
}
void
f8 (struct S *x)
{
- __asm ("" : "=r" (*x)); /* { dg-error "invalid lvalue in 'asm' output 0" } */
+ __asm ("" : "=r" (*x)); /* { dg-error "impossible constraint in 'asm'" } */
+ /* { dg-error "non-memory output 0 must stay in memory" "memory" { target *-*-* } .-1 } */
}
===================================================================
@@ -7,15 +7,15 @@ union U;
int
f1 (struct S *s)
{
- return s->a /* { dg-error "dereferencing pointer to incomplete type .struct S." } */
- + s->b
- + s->c;
+ return s->a /* { dg-error "invalid use of undefined type .struct S." } */
+ + s->b /* { dg-error "invalid use of undefined type .struct S." } */
+ + s->c; /* { dg-error "invalid use of undefined type .struct S." } */
}
int
f2 (union U *u)
{
- return u->a /* { dg-error "dereferencing pointer to incomplete type .union U." } */
- + u->a
- + u->a;
+ return u->a /* { dg-error "invalid use of undefined type .union U." } */
+ + u->a /* { dg-error "invalid use of undefined type .union U." } */
+ + u->a; /* { dg-error "invalid use of undefined type .union U." } */
}
===================================================================
@@ -6,5 +6,5 @@ struct S s; /* { dg-error "storage size of 's' isn
void
foo ()
{
- s a; /* { dg-error "expression statement has incomplete type|expected" } */
+ s a; /* { dg-error "has an incomplete type|expected" } */
}