https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/132238

Don't call CheckActive for copy/move operators. They will activate the union 
member.

>From 5729d5f04578ea5628f22bfb3cc71826bdacb9e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Thu, 20 Mar 2025 07:03:07 +0100
Subject: [PATCH] [clang][bytecode] Fix union copy/move operator active check

Don't call CheckActive for copy/move operators. They will activate
the union member.
---
 clang/lib/AST/ByteCode/Function.cpp |  4 +++-
 clang/lib/AST/ByteCode/Function.h   |  5 +++++
 clang/lib/AST/ByteCode/Interp.cpp   |  1 +
 clang/test/AST/ByteCode/unions.cpp  | 29 +++++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Function.cpp 
b/clang/lib/AST/ByteCode/Function.cpp
index fa803070c821d..764aa4a851cf4 100644
--- a/clang/lib/AST/ByteCode/Function.cpp
+++ b/clang/lib/AST/ByteCode/Function.cpp
@@ -35,10 +35,12 @@ Function::Function(Program &P, FunctionDeclTy Source, 
unsigned ArgSize,
       Kind = FunctionKind::Dtor;
     } else if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
       Virtual = MD->isVirtual();
-      if (IsLambdaStaticInvoker) // MD->isLambdaStaticInvoker())
+      if (IsLambdaStaticInvoker)
         Kind = FunctionKind::LambdaStaticInvoker;
       else if (clang::isLambdaCallOperator(F))
         Kind = FunctionKind::LambdaCallOperator;
+      else if (MD->isCopyAssignmentOperator() || 
MD->isMoveAssignmentOperator())
+        Kind = FunctionKind::CopyOrMoveOperator;
     }
   }
 }
diff --git a/clang/lib/AST/ByteCode/Function.h 
b/clang/lib/AST/ByteCode/Function.h
index cdf98f9e67dde..c114cfe5ba29a 100644
--- a/clang/lib/AST/ByteCode/Function.h
+++ b/clang/lib/AST/ByteCode/Function.h
@@ -91,6 +91,7 @@ class Function final {
     Dtor,
     LambdaStaticInvoker,
     LambdaCallOperator,
+    CopyOrMoveOperator,
   };
   using ParamDescriptor = std::pair<PrimType, Descriptor *>;
 
@@ -159,6 +160,10 @@ class Function final {
   bool isConstructor() const { return Kind == FunctionKind::Ctor; }
   /// Checks if the function is a destructor.
   bool isDestructor() const { return Kind == FunctionKind::Dtor; }
+  /// Checks if the function is copy or move operator.
+  bool isCopyOrMoveOperator() const {
+    return Kind == FunctionKind::CopyOrMoveOperator;
+  }
 
   /// Returns whether this function is a lambda static invoker,
   /// which we generate custom byte code for.
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index b4ea825ce472c..a3a2a7c82a47f 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1449,6 +1449,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
       if (!CheckInvoke(S, OpPC, ThisPtr))
         return cleanup();
       if (!Func->isConstructor() && !Func->isDestructor() &&
+          !Func->isCopyOrMoveOperator() &&
           !CheckActive(S, OpPC, ThisPtr, AK_MemberCall))
         return false;
     }
diff --git a/clang/test/AST/ByteCode/unions.cpp 
b/clang/test/AST/ByteCode/unions.cpp
index 70524fd36bcc2..66b8389606b85 100644
--- a/clang/test/AST/ByteCode/unions.cpp
+++ b/clang/test/AST/ByteCode/unions.cpp
@@ -570,4 +570,33 @@ namespace ActiveDestroy {
   static_assert(foo2());
 }
 
+namespace MoveOrAssignOp {
+  struct min_pointer {
+    int *ptr_;
+    constexpr min_pointer(int *p) : ptr_(p) {}
+    min_pointer() = default;
+  };
+
+  class F {
+    struct __long {
+      min_pointer __data_;
+    };
+    union __rep {
+      int __s;
+      __long __l;
+    } __rep_;
+
+  public:
+    constexpr F() {
+      __rep_ = __rep();
+      __rep_.__l.__data_ = nullptr;
+    }
+  };
+
+  constexpr bool foo() {
+    F f{};
+    return true;
+  }
+  static_assert(foo());
+}
 #endif

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to