[clang] [clang][bytecode] Add special handling for union copy assign operators (PR #125476)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 3 02:47:52 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/125476.diff
3 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+25-4)
- (modified) clang/lib/AST/ByteCode/Compiler.h (+1)
- (modified) clang/test/AST/ByteCode/unions.cpp (+29-1)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index b9e22ebb7a41a9..f23472f99ac1b5 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4676,7 +4676,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
OCE && OCE->isAssignmentOp()) {
// Just like with regular assignments, we need to special-case assignment
// operators here and evaluate the RHS (the second arg) before the LHS (the
- // first arg. We fix this by using a Flip op later.
+ // first arg). We fix this by using a Flip op later.
assert(Args.size() == 2);
IsAssignmentOperatorCall = true;
std::reverse(Args.begin(), Args.end());
@@ -5664,6 +5664,21 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor);
}
+template <class Emitter>
+bool Compiler<Emitter>::compileUnionCopyAssignmentOperator(
+ const CXXMethodDecl *MD) {
+ if (!this->emitThis(MD))
+ return false;
+
+ auto PVD = MD->getParamDecl(0);
+ ParamOffset PO = this->Params[PVD]; // Must exist.
+
+ if (!this->emitGetParam(PT_Ptr, PO.Offset, MD))
+ return false;
+
+ return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD);
+}
+
template <class Emitter>
bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
// Classify the return type.
@@ -5675,9 +5690,15 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
return this->compileDestructor(Dtor);
// Emit custom code if this is a lambda static invoker.
- if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
- MD && MD->isLambdaStaticInvoker())
- return this->emitLambdaStaticInvokerBody(MD);
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
+ const RecordDecl *RD = MD->getParent();
+
+ if (RD->isUnion() && MD->isCopyAssignmentOperator())
+ return this->compileUnionCopyAssignmentOperator(MD);
+
+ if (MD->isLambdaStaticInvoker())
+ return this->emitLambdaStaticInvokerBody(MD);
+ }
// Regular functions.
if (const auto *Body = F->getBody())
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 5a02f38d78dec8..ecf50662d617bc 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -383,6 +383,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool emitBuiltinBitCast(const CastExpr *E);
bool compileConstructor(const CXXConstructorDecl *Ctor);
bool compileDestructor(const CXXDestructorDecl *Dtor);
+ bool compileUnionCopyAssignmentOperator(const CXXMethodDecl *MD);
bool checkLiteralType(const Expr *E);
diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp
index e90b123c90de0e..0a1f0f88650f27 100644
--- a/clang/test/AST/ByteCode/unions.cpp
+++ b/clang/test/AST/ByteCode/unions.cpp
@@ -402,7 +402,6 @@ namespace UnionInBase {
static_assert(return_uninit().a.x == 2);
}
-/// FIXME: Our diagnostic here is a little off.
namespace One {
struct A { long x; };
@@ -421,4 +420,33 @@ namespace One {
// both-note {{constinit}}
}
+namespace CopyAssign {
+ union A {
+ int a;
+ int b;
+ };
+
+ constexpr int f() {
+ A a{12};
+ A b{13};
+
+ b.b = 32;
+ b = a ;
+ return b.a;
+ }
+ static_assert(f()== 12);
+
+
+ constexpr int f2() {
+ A a{12};
+ A b{13};
+
+ b.b = 32;
+ b = a ;
+ return b.b; // both-note {{read of member 'b' of union with active member 'a'}}
+ }
+ static_assert(f2() == 12); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
+
+}
#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/125476
More information about the cfe-commits
mailing list