diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3ea177ffbd6..f9c6293d9e5 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,13 @@ +2019-12-04 Joseph Myers + + 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 PR c/88704 diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index cdfb9080346..ff2345dbe68 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -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) diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index f9ab1e38b42..36aedc063d2 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2054,6 +2054,8 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr 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 *params; @@ -2550,16 +2552,6 @@ build_indirect_ref (location_t loc, tree ptr, ref_operator errstring) 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 % pointer"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7678625820f..48a6d4501ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2019-12-04 Joseph Myers + + 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 * gcc.target/aarch64/sve/acle/general/whilelt_5.c: New test. diff --git a/gcc/testsuite/gcc.dg/array-8.c b/gcc/testsuite/gcc.dg/array-8.c index 644d84f14aa..71c98038b86 100644 --- a/gcc/testsuite/gcc.dg/array-8.c +++ b/gcc/testsuite/gcc.dg/array-8.c @@ -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'" } */ } diff --git a/gcc/testsuite/gcc.dg/enum-incomplete-1.c b/gcc/testsuite/gcc.dg/enum-incomplete-1.c index 06c247c2e51..2da3b58f54c 100644 --- a/gcc/testsuite/gcc.dg/enum-incomplete-1.c +++ b/gcc/testsuite/gcc.dg/enum-incomplete-1.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/enum-incomplete-3.c b/gcc/testsuite/gcc.dg/enum-incomplete-3.c index db1138b56c6..12280db61fb 100644 --- a/gcc/testsuite/gcc.dg/enum-incomplete-3.c +++ b/gcc/testsuite/gcc.dg/enum-incomplete-3.c @@ -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" } */ }; } diff --git a/gcc/testsuite/gcc.dg/lvalue-10.c b/gcc/testsuite/gcc.dg/lvalue-10.c new file mode 100644 index 00000000000..cc5f37ba964 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lvalue-10.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/lvalue-9.c b/gcc/testsuite/gcc.dg/lvalue-9.c new file mode 100644 index 00000000000..382b3ffa903 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lvalue-9.c @@ -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" } */ +} diff --git a/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c b/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c index 735ef465b38..0618b4d8170 100644 --- a/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c +++ b/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c @@ -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" } */ } diff --git a/gcc/testsuite/gcc.dg/pr48552-1.c b/gcc/testsuite/gcc.dg/pr48552-1.c index 70d3483d80c..11ee401e030 100644 --- a/gcc/testsuite/gcc.dg/pr48552-1.c +++ b/gcc/testsuite/gcc.dg/pr48552-1.c @@ -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 } */ } diff --git a/gcc/testsuite/gcc.dg/pr48552-2.c b/gcc/testsuite/gcc.dg/pr48552-2.c index ce6bece3f96..2d2a00c43b7 100644 --- a/gcc/testsuite/gcc.dg/pr48552-2.c +++ b/gcc/testsuite/gcc.dg/pr48552-2.c @@ -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 } */ } diff --git a/gcc/testsuite/gcc.dg/pr63543.c b/gcc/testsuite/gcc.dg/pr63543.c index 215b62ed911..d85e10d2021 100644 --- a/gcc/testsuite/gcc.dg/pr63543.c +++ b/gcc/testsuite/gcc.dg/pr63543.c @@ -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." } */ } diff --git a/gcc/testsuite/gcc.dg/pr69796.c b/gcc/testsuite/gcc.dg/pr69796.c index ebf34aaa216..4b725a50767 100644 --- a/gcc/testsuite/gcc.dg/pr69796.c +++ b/gcc/testsuite/gcc.dg/pr69796.c @@ -6,5 +6,5 @@ struct S s; /* { dg-error "storage size of 's' isn't known" } */ void foo () { - s a; /* { dg-error "expression statement has incomplete type|expected" } */ + s a; /* { dg-error "has an incomplete type|expected" } */ }