aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-02-28 09:58:36 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-02-28 12:38:00 +0100
commit95f5d6cc17e7d6b689674756c62b6b5e1284afd0 (patch)
treeef06ad8a285b1fa51d9411cbc2e61a62f353d91a /gcc
parent616d1bd1ae28bb7617a21eb9d118e2bbeb01a409 (diff)
downloadgcc-95f5d6cc17e7d6b689674756c62b6b5e1284afd0.zip
gcc-95f5d6cc17e7d6b689674756c62b6b5e1284afd0.tar.gz
gcc-95f5d6cc17e7d6b689674756c62b6b5e1284afd0.tar.bz2
middle-end/66279 - gimplification clobbers shared asm constraints
When the C++ frontend clones a CTOR we do not copy ASM_EXPR constraints fully as walk_tree does not recurse to TREE_PURPOSE of TREE_LIST nodes. At this point doing that seems too dangerous so the following instead avoids gimplification of ASM_EXPRs to clobber the shared constraints and unshares it there, like it also unshares TREE_VALUE when it re-writes a "+" output constraint to separate "=" output and matching input constraint. PR middle-end/66279 * gimplify.cc (gimplify_asm_expr): Copy TREE_PURPOSE before rewriting it for "+" processing. * g++.dg/pr66279.C: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimplify.cc1
-rw-r--r--gcc/testsuite/g++.dg/pr66279.C23
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 756cdea..160e7fc 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -7810,6 +7810,7 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
/* Turn the in/out constraint into an output constraint. */
char *p = xstrdup (constraint);
p[0] = '=';
+ TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link));
TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
/* And add a matching input constraint. */
diff --git a/gcc/testsuite/g++.dg/pr66279.C b/gcc/testsuite/g++.dg/pr66279.C
new file mode 100644
index 0000000..c878044
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr66279.C
@@ -0,0 +1,23 @@
+// { dg-do run }
+
+struct A {};
+
+struct B : public virtual A
+{
+ B();
+};
+
+B::B()
+{
+ unsigned int x = 42;
+
+ __asm__ __volatile__ ("" : "+r"(x));
+
+ if (x != 42)
+ __builtin_abort ();
+}
+
+int main()
+{
+ B b;
+}