https://gcc.gnu.org/g:12b536c17d28500fa9ad32563ae6088726162051
commit r14-11500-g12b536c17d28500fa9ad32563ae6088726162051 Author: Richard Biener <rguent...@suse.de> Date: Fri Feb 28 09:58:36 2025 +0100 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. (cherry picked from commit 95f5d6cc17e7d6b689674756c62b6b5e1284afd0) Diff: --- gcc/gimplify.cc | 1 + gcc/testsuite/g++.dg/pr66279.C | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 32ecb0cffe5d..a4972d3f471e 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -7084,6 +7084,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 000000000000..c878044a83b3 --- /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; +}