Skip to content

Commit 49f0607

Browse files
authored
[clang][bytecode] Fix union copy/move operator active check (#132238)
Don't call CheckActive for copy/move operators. They will activate the union member.
1 parent 882082a commit 49f0607

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

clang/lib/AST/ByteCode/Function.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
3535
Kind = FunctionKind::Dtor;
3636
} else if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
3737
Virtual = MD->isVirtual();
38-
if (IsLambdaStaticInvoker) // MD->isLambdaStaticInvoker())
38+
if (IsLambdaStaticInvoker)
3939
Kind = FunctionKind::LambdaStaticInvoker;
4040
else if (clang::isLambdaCallOperator(F))
4141
Kind = FunctionKind::LambdaCallOperator;
42+
else if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())
43+
Kind = FunctionKind::CopyOrMoveOperator;
4244
}
4345
}
4446
}

clang/lib/AST/ByteCode/Function.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class Function final {
9191
Dtor,
9292
LambdaStaticInvoker,
9393
LambdaCallOperator,
94+
CopyOrMoveOperator,
9495
};
9596
using ParamDescriptor = std::pair<PrimType, Descriptor *>;
9697

@@ -159,6 +160,10 @@ class Function final {
159160
bool isConstructor() const { return Kind == FunctionKind::Ctor; }
160161
/// Checks if the function is a destructor.
161162
bool isDestructor() const { return Kind == FunctionKind::Dtor; }
163+
/// Checks if the function is copy or move operator.
164+
bool isCopyOrMoveOperator() const {
165+
return Kind == FunctionKind::CopyOrMoveOperator;
166+
}
162167

163168
/// Returns whether this function is a lambda static invoker,
164169
/// which we generate custom byte code for.

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
14491449
if (!CheckInvoke(S, OpPC, ThisPtr))
14501450
return cleanup();
14511451
if (!Func->isConstructor() && !Func->isDestructor() &&
1452+
!Func->isCopyOrMoveOperator() &&
14521453
!CheckActive(S, OpPC, ThisPtr, AK_MemberCall))
14531454
return false;
14541455
}

clang/test/AST/ByteCode/unions.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,4 +570,33 @@ namespace ActiveDestroy {
570570
static_assert(foo2());
571571
}
572572

573+
namespace MoveOrAssignOp {
574+
struct min_pointer {
575+
int *ptr_;
576+
constexpr min_pointer(int *p) : ptr_(p) {}
577+
min_pointer() = default;
578+
};
579+
580+
class F {
581+
struct __long {
582+
min_pointer __data_;
583+
};
584+
union __rep {
585+
int __s;
586+
__long __l;
587+
} __rep_;
588+
589+
public:
590+
constexpr F() {
591+
__rep_ = __rep();
592+
__rep_.__l.__data_ = nullptr;
593+
}
594+
};
595+
596+
constexpr bool foo() {
597+
F f{};
598+
return true;
599+
}
600+
static_assert(foo());
601+
}
573602
#endif

0 commit comments

Comments
 (0)