* [C PATCH] Fix regression causing ICE for structs with VLAs [PR 112488]
@ 2023-12-08 16:43 Martin Uecker
2023-12-09 19:58 ` v2 " Martin Uecker
0 siblings, 1 reply; 3+ messages in thread
From: Martin Uecker @ 2023-12-08 16:43 UTC (permalink / raw)
To: gcc-patches; +Cc: Joseph Myers, Richard Biener
This fixes a regression caused by my previous VM fixes.
Fix regression causing ICE for structs with VLAs [PR 112488]
A previous patch the fixed several ICEs related to size expressions
of VM types (PR c/70418, ...) caused a regression for structs where
a DECL_EXPR is not generated anymore although reqired. We now call
add_decl_expr introduced by the previous patch from finish_struct.
The function gets a new argument to not set the TYPE_NAME for the
type to the DECL_EXPR in this spicitic case.
PR c/112488
gcc/c
* c-decl.cc (add_decl_expr): Add argument.
(finish_struct): Create DECL_EXPR.
(c_simulate_record_decl): Adapt.
* c-parser.cc (c_parser_struct_or_union_specifier): Call
finish_struct with expression for VLA sizes.
* c-tree.h (finish_struct): Add argument.
gcc/testsuite
* gcc.dg/pr112488-1.c: New test.
* gcc.dg/pr112488-2.c: New test.
* gcc.dg/pr112898.c: New test.
* gcc.misc-tests/gcov-pr85350.c: Adapt.
---
gcc/c/c-decl.cc | 22 +++++++++++++++------
gcc/c/c-parser.cc | 2 +-
gcc/c/c-tree.h | 3 ++-
gcc/testsuite/gcc.dg/pr112488-1.c | 14 +++++++++++++
gcc/testsuite/gcc.dg/pr112488-2.c | 13 ++++++++++++
gcc/testsuite/gcc.dg/pr112898.c | 9 +++++++++
gcc/testsuite/gcc.misc-tests/gcov-pr85350.c | 2 +-
7 files changed, 56 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr112488-1.c
create mode 100644 gcc/testsuite/gcc.dg/pr112488-2.c
create mode 100644 gcc/testsuite/gcc.dg/pr112898.c
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 92c83e1bf10..0b500c19e70 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6619,7 +6619,7 @@ smallest_type_quals_location (const location_t *locations,
use BIND_EXPRs in TYPENAME contexts too. */
static void
add_decl_expr (location_t loc, enum decl_context decl_context, tree type,
- tree *expr)
+ tree *expr, bool set_name_p)
{
tree bind = NULL_TREE;
if (decl_context == TYPENAME || decl_context == PARM
@@ -6636,7 +6636,8 @@ add_decl_expr (location_t loc, enum decl_context decl_context, tree type,
pushdecl (decl);
DECL_ARTIFICIAL (decl) = 1;
add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
- TYPE_NAME (type) = decl;
+ if (set_name_p)
+ TYPE_NAME (type) = decl;
if (bind)
{
@@ -7635,7 +7636,7 @@ grokdeclarator (const struct c_declarator *declarator,
type has a name/declaration of it's own, but special attention
is required if the type is anonymous. */
if (!TYPE_NAME (type) && c_type_variably_modified_p (type))
- add_decl_expr (loc, decl_context, type, expr);
+ add_decl_expr (loc, decl_context, type, expr, true);
type = c_build_pointer_type (type);
@@ -7900,7 +7901,7 @@ grokdeclarator (const struct c_declarator *declarator,
/* The pointed-to type may need a decl expr (see above). */
if (!TYPE_NAME (type) && c_type_variably_modified_p (type))
- add_decl_expr (loc, decl_context, type, expr);
+ add_decl_expr (loc, decl_context, type, expr, true);
type = c_build_pointer_type (type);
type_quals = array_ptr_quals;
@@ -9257,7 +9258,8 @@ is_flexible_array_member_p (bool is_last_field,
tree
finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
- class c_struct_parse_info *enclosing_struct_parse_info)
+ class c_struct_parse_info *enclosing_struct_parse_info,
+ tree *expr)
{
tree x;
bool toplevel = file_scope == current_scope;
@@ -9595,6 +9597,13 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
finish_incomplete_vars (incomplete_vars, toplevel);
+ /* Make sure a DECL_EXPR is created for structs with VLA members.
+ Because we do not know the context, we use decl_context TYPENAME
+ here to force creation of a BIND_EXPR which is required in some
+ contexts. */
+ if (c_type_variably_modified_p (t))
+ add_decl_expr (loc, TYPENAME, t, expr, false);
+
if (warn_cxx_compat)
warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc);
@@ -10191,7 +10200,8 @@ c_simulate_record_decl (location_t loc, const char *name,
DECL_CHAIN (fields[i - 1]) = fields[i];
}
- finish_struct (loc, type, fields[0], NULL_TREE, struct_info);
+ tree expr = NULL_TREE;
+ finish_struct (loc, type, fields[0], NULL_TREE, struct_info, &expr);
tree decl = build_decl (loc, TYPE_DECL, ident, type);
set_underlying_type (decl);
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index df9a07928b5..dcb6c21da41 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -4087,7 +4087,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
ret.spec = finish_struct (struct_loc, type, nreverse (contents),
chainon (std_attrs,
chainon (attrs, postfix_attrs)),
- struct_info);
+ struct_info, &expr);
ret.kind = ctsk_tagdef;
ret.expr = expr;
ret.expr_const_operands = true;
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index d0bdc3df2c2..da8ee8b40f0 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -656,7 +656,8 @@ extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
extern void finish_function (location_t = input_location);
extern tree finish_struct (location_t, tree, tree, tree,
- class c_struct_parse_info *);
+ class c_struct_parse_info *,
+ tree *expr);
extern tree c_simulate_enum_decl (location_t, const char *,
vec<string_int_pair> *);
extern tree c_simulate_record_decl (location_t, const char *,
diff --git a/gcc/testsuite/gcc.dg/pr112488-1.c b/gcc/testsuite/gcc.dg/pr112488-1.c
new file mode 100644
index 00000000000..b53295c4366
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112488-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile }
+ * { dg-options "-O1" } */
+
+extern void abort(void);
+
+int test(int *n) {
+ struct T { char a[*n], b[*n]; };
+ return sizeof(struct T) - sizeof(struct T);
+}
+
+void f1(int *p) {
+ if (!test(p)) abort();
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr112488-2.c b/gcc/testsuite/gcc.dg/pr112488-2.c
new file mode 100644
index 00000000000..b5e5fbd3f2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112488-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile }
+ * { dg-options "-std=gnu23 -O1" } */
+
+extern void abort(void);
+
+int test(int *n, struct T { char a[*n], b[*n]; }*) {
+ return sizeof(struct T) - sizeof(struct T);
+}
+
+void f1(int *p) {
+ if (test(p, 0)) abort();
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr112898.c b/gcc/testsuite/gcc.dg/pr112898.c
new file mode 100644
index 00000000000..395f3afaf2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112898.c
@@ -0,0 +1,9 @@
+/* { dg-do compile }
+ { dg-options "-O2 -finstrument-functions-once" } */
+
+void func(int n)
+{
+ struct T { int x[n]; };
+ struct T *t = __builtin_malloc(sizeof *t);
+}
+
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
index a42bf1282b2..0383b81fdfb 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
@@ -4,7 +4,7 @@
int main (void)
{
const int t = 2; /* count(1) */
- struct s1 { /* count(-) */
+ struct s1 { /* count(1) */
int x;
int g[t];
};
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* v2 [C PATCH] Fix regression causing ICE for structs with VLAs [PR 112488]
2023-12-08 16:43 [C PATCH] Fix regression causing ICE for structs with VLAs [PR 112488] Martin Uecker
@ 2023-12-09 19:58 ` Martin Uecker
2023-12-11 21:02 ` Joseph Myers
0 siblings, 1 reply; 3+ messages in thread
From: Martin Uecker @ 2023-12-09 19:58 UTC (permalink / raw)
To: gcc-patches; +Cc: Joseph Myers, Richard Biener
I revised version which fixes a problem with breaking other
callers of finish_rust. Please ignore the previous one.
Bootstrapped and regression tested on x86_64
Fix regression causing ICE for structs with VLAs [PR 112488]
A previous patch the fixed several ICEs related to size expressions
of VM types (PR c/70418, ...) caused a regression for structs where
a DECL_EXPR is not generated anymore although reqired. We now call
add_decl_expr introduced by the previous patch from finish_struct.
The function is revised with a new argument to not set the TYPE_NAME
for the type to the DECL_EXPR in this specific case.
PR c/112488
gcc/c
* c-decl.cc (add_decl_expr): Revise.
(finish_struct): Create DECL_EXPR.
* c-parser.cc (c_parser_struct_or_union_specifier): Call
finish_struct with expression for VLA sizes.
* c-tree.h (finish_struct): Add argument.
gcc/testsuite
* gcc.dg/pr112488-1.c: New test.
* gcc.dg/pr112488-2.c: New test.
* gcc.dg/pr112898.c: New test.
* gcc.misc-tests/gcov-pr85350.c: Adapt.
---
gcc/c/c-decl.cc | 33 ++++++++++++++++-----
gcc/c/c-parser.cc | 2 +-
gcc/c/c-tree.h | 3 +-
gcc/testsuite/gcc.dg/pr112488-1.c | 14 +++++++++
gcc/testsuite/gcc.dg/pr112488-2.c | 13 ++++++++
gcc/testsuite/gcc.dg/pr112898.c | 9 ++++++
gcc/testsuite/gcc.misc-tests/gcov-pr85350.c | 2 +-
7 files changed, 65 insertions(+), 11 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr112488-1.c
create mode 100644 gcc/testsuite/gcc.dg/pr112488-2.c
create mode 100644 gcc/testsuite/gcc.dg/pr112898.c
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 92c83e1bf10..039a66fef09 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6618,12 +6618,10 @@ smallest_type_quals_location (const location_t *locations,
the size evaluation prior to the side effects. We therefore
use BIND_EXPRs in TYPENAME contexts too. */
static void
-add_decl_expr (location_t loc, enum decl_context decl_context, tree type,
- tree *expr)
+add_decl_expr (location_t loc, tree type, tree *expr, bool set_name_p)
{
tree bind = NULL_TREE;
- if (decl_context == TYPENAME || decl_context == PARM
- || decl_context == FIELD)
+ if (expr)
{
bind = build3 (BIND_EXPR, void_type_node, NULL_TREE, NULL_TREE,
NULL_TREE);
@@ -6636,7 +6634,8 @@ add_decl_expr (location_t loc, enum decl_context decl_context, tree type,
pushdecl (decl);
DECL_ARTIFICIAL (decl) = 1;
add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
- TYPE_NAME (type) = decl;
+ if (set_name_p)
+ TYPE_NAME (type) = decl;
if (bind)
{
@@ -7635,7 +7634,12 @@ grokdeclarator (const struct c_declarator *declarator,
type has a name/declaration of it's own, but special attention
is required if the type is anonymous. */
if (!TYPE_NAME (type) && c_type_variably_modified_p (type))
- add_decl_expr (loc, decl_context, type, expr);
+ {
+ bool bind_p = decl_context == TYPENAME
+ || decl_context == FIELD
+ || decl_context == PARM;
+ add_decl_expr (loc, type, bind_p ? expr : NULL, true);
+ }
type = c_build_pointer_type (type);
@@ -7900,7 +7904,12 @@ grokdeclarator (const struct c_declarator *declarator,
/* The pointed-to type may need a decl expr (see above). */
if (!TYPE_NAME (type) && c_type_variably_modified_p (type))
- add_decl_expr (loc, decl_context, type, expr);
+ {
+ bool bind_p = decl_context == TYPENAME
+ || decl_context == FIELD
+ || decl_context == PARM;
+ add_decl_expr (loc, type, bind_p ? expr : NULL, true);
+ }
type = c_build_pointer_type (type);
type_quals = array_ptr_quals;
@@ -9257,7 +9266,8 @@ is_flexible_array_member_p (bool is_last_field,
tree
finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
- class c_struct_parse_info *enclosing_struct_parse_info)
+ class c_struct_parse_info *enclosing_struct_parse_info,
+ tree *expr)
{
tree x;
bool toplevel = file_scope == current_scope;
@@ -9595,6 +9605,13 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
finish_incomplete_vars (incomplete_vars, toplevel);
+ /* Make sure a DECL_EXPR is created for structs with VLA members.
+ Because we do not know the context, we always pass expr
+ to force creation of a BIND_EXPR which is required in some
+ contexts. */
+ if (c_type_variably_modified_p (t))
+ add_decl_expr (loc, t, expr, false);
+
if (warn_cxx_compat)
warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc);
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index df9a07928b5..dcb6c21da41 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -4087,7 +4087,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
ret.spec = finish_struct (struct_loc, type, nreverse (contents),
chainon (std_attrs,
chainon (attrs, postfix_attrs)),
- struct_info);
+ struct_info, &expr);
ret.kind = ctsk_tagdef;
ret.expr = expr;
ret.expr_const_operands = true;
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index d0bdc3df2c2..b325723a734 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -656,7 +656,8 @@ extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
extern void finish_function (location_t = input_location);
extern tree finish_struct (location_t, tree, tree, tree,
- class c_struct_parse_info *);
+ class c_struct_parse_info *,
+ tree *expr = NULL);
extern tree c_simulate_enum_decl (location_t, const char *,
vec<string_int_pair> *);
extern tree c_simulate_record_decl (location_t, const char *,
diff --git a/gcc/testsuite/gcc.dg/pr112488-1.c b/gcc/testsuite/gcc.dg/pr112488-1.c
new file mode 100644
index 00000000000..b53295c4366
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112488-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile }
+ * { dg-options "-O1" } */
+
+extern void abort(void);
+
+int test(int *n) {
+ struct T { char a[*n], b[*n]; };
+ return sizeof(struct T) - sizeof(struct T);
+}
+
+void f1(int *p) {
+ if (!test(p)) abort();
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr112488-2.c b/gcc/testsuite/gcc.dg/pr112488-2.c
new file mode 100644
index 00000000000..b5e5fbd3f2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112488-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile }
+ * { dg-options "-std=gnu23 -O1" } */
+
+extern void abort(void);
+
+int test(int *n, struct T { char a[*n], b[*n]; }*) {
+ return sizeof(struct T) - sizeof(struct T);
+}
+
+void f1(int *p) {
+ if (test(p, 0)) abort();
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr112898.c b/gcc/testsuite/gcc.dg/pr112898.c
new file mode 100644
index 00000000000..395f3afaf2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr112898.c
@@ -0,0 +1,9 @@
+/* { dg-do compile }
+ { dg-options "-O2 -finstrument-functions-once" } */
+
+void func(int n)
+{
+ struct T { int x[n]; };
+ struct T *t = __builtin_malloc(sizeof *t);
+}
+
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
index a42bf1282b2..0383b81fdfb 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
@@ -4,7 +4,7 @@
int main (void)
{
const int t = 2; /* count(1) */
- struct s1 { /* count(-) */
+ struct s1 { /* count(1) */
int x;
int g[t];
};
--
2.39.2
.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: v2 [C PATCH] Fix regression causing ICE for structs with VLAs [PR 112488]
2023-12-09 19:58 ` v2 " Martin Uecker
@ 2023-12-11 21:02 ` Joseph Myers
0 siblings, 0 replies; 3+ messages in thread
From: Joseph Myers @ 2023-12-11 21:02 UTC (permalink / raw)
To: Martin Uecker; +Cc: gcc-patches, Richard Biener
On Sat, 9 Dec 2023, Martin Uecker wrote:
> Fix regression causing ICE for structs with VLAs [PR 112488]
>
> A previous patch the fixed several ICEs related to size expressions
> of VM types (PR c/70418, ...) caused a regression for structs where
> a DECL_EXPR is not generated anymore although reqired. We now call
> add_decl_expr introduced by the previous patch from finish_struct.
> The function is revised with a new argument to not set the TYPE_NAME
> for the type to the DECL_EXPR in this specific case.
OK.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-12-11 21:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-08 16:43 [C PATCH] Fix regression causing ICE for structs with VLAs [PR 112488] Martin Uecker
2023-12-09 19:58 ` v2 " Martin Uecker
2023-12-11 21:02 ` Joseph Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).