aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>2025-09-15 09:10:53 +0200
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>2025-09-15 09:10:53 +0200
commit4cff794ca18a96ceeb83ccb18b08ffa0a63c58af (patch)
treeb07ce1f3951da47b6979ab92d4bc68d89dc4c224
parent8d264d90a22d5e13c876a4f352c702c7f5bc4f0b (diff)
downloadgcc-4cff794ca18a96ceeb83ccb18b08ffa0a63c58af.zip
gcc-4cff794ca18a96ceeb83ccb18b08ffa0a63c58af.tar.gz
gcc-4cff794ca18a96ceeb83ccb18b08ffa0a63c58af.tar.bz2
Bail out early during gimplify_asm_expr [PR121391]
In case an asm operand is an error node, constraints etc. are still validated. Furthermore, all other operands are gimplified, although an error is returned in the end anyway. For hard register constraints an operand is required in order to determine the mode from which the number of registers follows. Therefore, instead of adding extra guards, bail out early. gcc/ChangeLog: PR middle-end/121391 * gimplify.cc (gimplify_asm_expr): In case an asm operand is an error node, bail out early. gcc/testsuite/ChangeLog: * gcc.dg/pr121391-1.c: New test. * gcc.dg/pr121391-2.c: New test.
-rw-r--r--gcc/gimplify.cc18
-rw-r--r--gcc/testsuite/gcc.dg/pr121391-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr121391-2.c9
3 files changed, 28 insertions, 8 deletions
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index ca1fa21..9009683 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -7930,6 +7930,8 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
bool ok;
size_t constraint_len;
+ if (error_operand_p (TREE_VALUE (link)))
+ return GS_ERROR;
link_next = TREE_CHAIN (link);
oconstraints[i]
@@ -7951,10 +7953,9 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
/* If we can't make copies, we can only accept memory.
Similarly for VLAs. */
tree outtype = TREE_TYPE (TREE_VALUE (link));
- if (outtype != error_mark_node
- && (TREE_ADDRESSABLE (outtype)
- || !COMPLETE_TYPE_P (outtype)
- || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
+ if (TREE_ADDRESSABLE (outtype)
+ || !COMPLETE_TYPE_P (outtype)
+ || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype)))
{
if (allows_mem)
allows_reg = 0;
@@ -8155,6 +8156,8 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
int input_num = 0;
for (link = ASM_INPUTS (expr); link; ++input_num, ++i, link = link_next)
{
+ if (error_operand_p (TREE_VALUE (link)))
+ return GS_ERROR;
link_next = TREE_CHAIN (link);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
reg_info.operand = TREE_VALUE (link);
@@ -8169,10 +8172,9 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
/* If we can't make copies, we can only accept memory. */
tree intype = TREE_TYPE (TREE_VALUE (link));
- if (intype != error_mark_node
- && (TREE_ADDRESSABLE (intype)
- || !COMPLETE_TYPE_P (intype)
- || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
+ if (TREE_ADDRESSABLE (intype)
+ || !COMPLETE_TYPE_P (intype)
+ || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype)))
{
if (allows_mem)
allows_reg = 0;
diff --git a/gcc/testsuite/gcc.dg/pr121391-1.c b/gcc/testsuite/gcc.dg/pr121391-1.c
new file mode 100644
index 0000000..6a01521
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr121391-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target aarch64*-*-* arm*-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */
+
+/* For the non existing variable we are faced with an error mark node during
+ gimplify_asm_expr(). */
+
+void test (void)
+{
+ __asm__ __volatile__ ("" : "={2}" (non_existing_var)); /* { dg-error {'non_existing_var' undeclared} } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr121391-2.c b/gcc/testsuite/gcc.dg/pr121391-2.c
new file mode 100644
index 0000000..c03f0ab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr121391-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target aarch64*-*-* arm*-*-* powerpc*-*-* s390*-*-* x86_64-*-* } } */
+
+/* For the non existing variable we are faced with an error mark node during
+ gimplify_asm_expr(). */
+
+void test (void)
+{
+ __asm__ __volatile__ ("" :: "{2}" (non_existing_var)); /* { dg-error {'non_existing_var' undeclared} } */
+}