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;
+}

Reply via email to