summaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp22
1 files changed, 14 insertions, 8 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 457de2bed37d..df5e3be83d74 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -326,7 +326,6 @@ bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
return true;
assert(Ptr.inUnion());
- assert(Ptr.isField() && Ptr.getField());
Pointer U = Ptr.getBase();
Pointer C = Ptr;
@@ -567,7 +566,10 @@ bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
assert(Ptr.isLive() && "Pointer is not live");
- if (!Ptr.isConst() || Ptr.isMutable())
+ if (!Ptr.isConst())
+ return true;
+
+ if (Ptr.isMutable() && !Ptr.isConstInMutable())
return true;
if (!Ptr.isBlockPointer())
@@ -575,7 +577,7 @@ bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
// The This pointer is writable in constructors and destructors,
// even if isConst() returns true.
- if (llvm::find(S.InitializingBlocks, Ptr.block()))
+ if (llvm::is_contained(S.InitializingBlocks, Ptr.block()))
return true;
const QualType Ty = Ptr.getType();
@@ -805,6 +807,8 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
return false;
if (!CheckRange(S, OpPC, Ptr, AK_Assign))
return false;
+ if (!CheckActive(S, OpPC, Ptr, AK_Assign))
+ return false;
if (!CheckGlobal(S, OpPC, Ptr))
return false;
if (!CheckConst(S, OpPC, Ptr))
@@ -814,7 +818,7 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
return true;
}
-bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
+static bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
if (!CheckLive(S, OpPC, Ptr, AK_MemberCall))
return false;
if (!Ptr.isDummy()) {
@@ -936,7 +940,7 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
return false;
}
-bool CheckCallDepth(InterpState &S, CodePtr OpPC) {
+static bool CheckCallDepth(InterpState &S, CodePtr OpPC) {
if ((S.Current->getDepth() + 1) > S.getLangOpts().ConstexprCallDepth) {
S.FFDiag(S.Current->getSource(OpPC),
diag::note_constexpr_depth_limit_exceeded)
@@ -1091,8 +1095,8 @@ bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
return false;
}
-bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F,
- const CallExpr *CE, unsigned ArgSize) {
+static bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F,
+ const CallExpr *CE, unsigned ArgSize) {
auto Args = ArrayRef(CE->getArgs(), CE->getNumArgs());
auto NonNullArgs = collectNonNullArgs(F->getDecl(), Args);
unsigned Offset = 0;
@@ -1500,7 +1504,6 @@ 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;
}
@@ -1773,6 +1776,9 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
std::optional<uint64_t> ArraySize) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
+ if (Ptr.inUnion() && Ptr.getBase().getRecord()->isUnion())
+ Ptr.activate();
+
// Similar to CheckStore(), but with the additional CheckTemporary() call and
// the AccessKinds are different.
if (!CheckTemporary(S, OpPC, Ptr, AK_Construct))