aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
diff options
context:
space:
mode:
authorNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 17:16:04 +0900
committerNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 17:16:04 +0900
commit0aa930a41f2d1ebf1fa90ec42da8f96d15a4dcbb (patch)
tree6a77b463f700e090df586672c26b9fe765fd115b /clang/lib/AST/ByteCode/Interp.cpp
parentec6892d1c979ce0b84c86918d5cdbb03037b409a (diff)
parent6d16b1c5c468a79ecf867293023c89ac518ecdda (diff)
downloadllvm-users/chapuni/cov/single/nextcount-base.zip
llvm-users/chapuni/cov/single/nextcount-base.tar.gz
llvm-users/chapuni/cov/single/nextcount-base.tar.bz2
Merge branch 'users/chapuni/cov/single/pair' into users/chapuni/cov/single/nextcount-baseusers/chapuni/cov/single/nextcount-base
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp82
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)