diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:43:11 +0900 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:43:11 +0900 |
commit | 0e1a753549b29ff1f5a190aca83b803a33b51628 (patch) | |
tree | e5578f8810c65711304128d0c8add7fa1f77b9d8 /clang/lib/AST/ByteCode/Interp.cpp | |
parent | 3c6252260ee11e3a453076b4d96ffffe20d49998 (diff) | |
parent | bdcf47e4bcb92889665825654bb80a8bbe30379e (diff) | |
download | llvm-users/chapuni/cov/single/if.zip llvm-users/chapuni/cov/single/if.tar.gz llvm-users/chapuni/cov/single/if.tar.bz2 |
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/ifusers/chapuni/cov/single/if
Conflicts:
clang/lib/CodeGen/CoverageMappingGen.cpp
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 7c77520..cb0ce886 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1154,6 +1154,53 @@ bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T) { return false; } +static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + uint32_t Off) { + if (S.getLangOpts().CPlusPlus && S.inConstantContext() && + !CheckNull(S, OpPC, Ptr, CSK_Field)) + return false; + + if (!CheckExtern(S, OpPC, Ptr)) + return false; + if (!CheckRange(S, OpPC, Ptr, CSK_Field)) + return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + if (!CheckSubobject(S, OpPC, Ptr, CSK_Field)) + return false; + + if (Ptr.isIntegralPointer()) { + S.Stk.push<Pointer>(Ptr.asIntPointer().atOffset(S.getASTContext(), Off)); + return true; + } + + if (!Ptr.isBlockPointer()) { + // FIXME: The only time we (seem to) get here is when trying to access a + // field of a typeid pointer. In that case, we're supposed to diagnose e.g. + // `typeid(int).name`, but we currently diagnose `&typeid(int)`. + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_access_unreadable_object) + << AK_Read << Ptr.toDiagnosticString(S.getASTContext()); + return false; + } + + if (Off > Ptr.block()->getSize()) + return false; + + S.Stk.push<Pointer>(Ptr.atField(Off)); + return true; +} + +bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) { + const auto &Ptr = S.Stk.peek<Pointer>(); + return getField(S, OpPC, Ptr, Off); +} + +bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off) { + const auto &Ptr = S.Stk.pop<Pointer>(); + return getField(S, OpPC, Ptr, Off); +} + static bool checkConstructor(InterpState &S, CodePtr OpPC, const Function *Func, const Pointer &ThisPtr) { assert(Func->isConstructor()); @@ -1595,6 +1642,41 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits, return false; } +bool GetTypeid(InterpState &S, CodePtr OpPC, const Type *TypePtr, + const Type *TypeInfoType) { + S.Stk.push<Pointer>(TypePtr, TypeInfoType); + return true; +} + +bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType) { + const auto &P = S.Stk.pop<Pointer>(); + + if (!P.isBlockPointer()) + return false; + + if (P.isDummy()) { + QualType StarThisType = + S.getASTContext().getLValueReferenceType(P.getType()); + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_polymorphic_unknown_dynamic_type) + << AK_TypeId + << P.toAPValue(S.getASTContext()) + .getAsString(S.getASTContext(), StarThisType); + return false; + } + + S.Stk.push<Pointer>(P.getType().getTypePtr(), TypeInfoType); + return true; +} + +bool DiagTypeid(InterpState &S, CodePtr OpPC) { + const auto *E = cast<CXXTypeidExpr>(S.Current->getExpr(OpPC)); + S.CCEDiag(E, diag::note_constexpr_typeid_polymorphic) + << E->getExprOperand()->getType() + << E->getExprOperand()->getSourceRange(); + return false; +} + // https://github.com/llvm/llvm-project/issues/102513 #if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG) #pragma optimize("", off) |