From: Martin Uecker Date: Thu, 12 Aug 2021 18:32:16 +0000 (+0200) Subject: Evaluate type arguments of sizeof that are structs of variable size [PR101838] X-Git-Tag: upstream/12.2.0~5815 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d2ba65ab6010f0d507bf5512a0223692e6653b23;p=platform%2Fupstream%2Fgcc.git Evaluate type arguments of sizeof that are structs of variable size [PR101838] Evaluate type arguments of sizeof for all types of variable size and not just for VLAs. This fixes PR101838 and some issues related to PR29970 where statement expressions need to be evaluated so that the size is well defined. 2021-08-12 Martin Uecker gcc/c/ PR c/101838 PR c/29970 * c-typeck.c (c_expr_sizeof_type): Evaluate size expressions for structs of variable size. gcc/testsuite/ PR c/101838 * gcc.dg/vla-stexp-2.c: New test. --- diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index c5bf337..eb5c87d 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3022,8 +3022,14 @@ c_expr_sizeof_type (location_t loc, struct c_type_name *t) c_last_sizeof_loc = loc; ret.original_code = SIZEOF_EXPR; ret.original_type = NULL; + if (type == error_mark_node) + { + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + } + else if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST) - && c_vla_type_p (type)) + && C_TYPE_VARIABLE_SIZE (type)) { /* If the type is a [*] array, it is a VLA but is represented as having a size of zero. In such a case we must ensure that diff --git a/gcc/testsuite/gcc.dg/vla-stexp-2.c b/gcc/testsuite/gcc.dg/vla-stexp-2.c new file mode 100644 index 0000000..176f400 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-stexp-2.c @@ -0,0 +1,33 @@ +/* PR101838 */ +/* { dg-do run } */ +/* { dg-options "-Wpedantic -O0" } */ + + +int bar0( + int (*a)[*], + int (*b)[sizeof(*a)] +); + + +int bar( + struct f { /* { dg-warning "will not be visible outside of this definition" } */ + int a[*]; } v, /* { dg-warning "variably modified type" } */ + int (*b)[sizeof(struct f)] // should not warn about zero size +); + +int foo(void) +{ + int n = 0; + return sizeof(typeof(*({ n = 10; struct foo { /* { dg-warning "braced-groups" } */ + int x[n]; /* { dg-warning "variably modified type" } */ + } x; &x; }))); +} + + +int main() +{ + if (sizeof(struct foo { int x[10]; }) != foo()) + __builtin_abort(); + + return 0; +}