+2019-12-04 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/36941
+ PR c/88827
+ * c-typeck.c (convert_lvalue_to_rvalue): Call
+ require_complete_type for arguments not of void types.
+ (build_indirect_ref): Do not diagnose dereferencing pointers to
+ incomplete types.
+ * c-tree.h (C_TYPE_ERROR_REPORTED): Remove.
+
2019-12-03 Joseph Myers <joseph@codesourcery.com>
PR c/88704
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)
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;
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");
+2019-12-04 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/36941
+ PR c/88827
+ * gcc.dg/lvalue-9.c, gcc.dg/lvalue-10.c: New tests.
+ * gcc.dg/array-8.c, gcc.dg/enum-incomplete-1.c,
+ gcc.dg/enum-incomplete-3.c, gcc.dg/noncompile/incomplete-3.c,
+ gcc.dg/pr48552-1.c, gcc.dg/pr48552-2.c, gcc.dg/pr63543.c,
+ gcc.dg/pr69796.c: Update expected diagnostics.
+
2019-12-04 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/sve/acle/general/whilelt_5.c: New test.
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'" } */
}
{
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" } */
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" } */
};
}
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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" } */
+}
{
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" } */
}
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 } */
}
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 } */
}
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." } */
}
void
foo ()
{
- s a; /* { dg-error "expression statement has incomplete type|expected" } */
+ s a; /* { dg-error "has an incomplete type|expected" } */
}