[clang] [clang][bytecode] Don't implicitly begin union member lifetime... (PR #192212)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 15 01:55:26 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
... on assignment operator calls if the LHS type does not have a non-deleted trivial default constructor.
---
Full diff: https://github.com/llvm/llvm-project/pull/192212.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-1)
- (modified) clang/test/AST/ByteCode/unions.cpp (+22)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 59510612d9617..a0d52c6580d74 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5601,6 +5601,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
SmallVector<const Expr *, 8> Args(ArrayRef(E->getArgs(), E->getNumArgs()));
bool IsAssignmentOperatorCall = false;
+ bool ActivateLHS = false;
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
OCE && OCE->isAssignmentOp()) {
// Just like with regular assignments, we need to special-case assignment
@@ -5609,6 +5610,9 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
assert(Args.size() == 2);
IsAssignmentOperatorCall = true;
std::reverse(Args.begin(), Args.end());
+ const CXXRecordDecl *LHSRecord = Args[0]->getType()->getAsCXXRecordDecl();
+ assert(LHSRecord);
+ ActivateLHS = LHSRecord->hasTrivialDefaultConstructor();
}
// Calling a static operator will still
// pass the instance, but we don't need it.
@@ -5684,7 +5688,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
return false;
}
- if (!this->visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall,
+ if (!this->visitCallArgs(Args, FuncDecl, ActivateLHS,
isa<CXXOperatorCallExpr>(E)))
return false;
diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp
index 2123a932fce10..d005b45795931 100644
--- a/clang/test/AST/ByteCode/unions.cpp
+++ b/clang/test/AST/ByteCode/unions.cpp
@@ -1007,4 +1007,26 @@ namespace NonTrivialUnionCtor {
static_assert(j()); // both-error {{not an integral constant expression}} \
// both-note {{in call to}}
}
+
+/// u.a should not implicitly get activated when assigning to it, since A
+/// does not have a non-deleted trivial default constructor.
+namespace NoTrivialCtor {
+ struct A {
+ int i;
+ constexpr A() : i(0) {}
+ constexpr A(int i) : i(i) {}
+ };
+
+ constexpr auto test() {
+ union U {
+ int i;
+ A a;
+ } u{.i = 0};
+
+ u.a = {123};
+ return u.a.i;
+ }
+
+ constexpr auto r = test();
+}
#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/192212
More information about the cfe-commits
mailing list