[clang] [clang] Add builtin_get_vtable_pointer and virtual_member_address (PR #135469)
Oliver Hunt via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 15 13:32:39 PDT 2025
================
@@ -1782,6 +1782,92 @@ static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call) {
return Call;
}
+static ExprResult VirtualMemberAddress(Sema &S, CallExpr *Call) {
+ if (S.checkArgCount(Call, 2))
+ return ExprError();
+
+ for (int i = 0; i < 2; ++i) {
+ ExprResult ArgRValue =
+ S.DefaultFunctionArrayLvalueConversion(Call->getArg(1));
+ if (ArgRValue.isInvalid())
+ return ExprError();
+ Call->setArg(1, ArgRValue.get());
+ }
+
+ if (Call->getArg(0)->isTypeDependent() || Call->getArg(1)->isValueDependent())
+ return Call;
+
+ const Expr *ThisArg = Call->getArg(0);
+ QualType ThisTy = ThisArg->getType();
+ if (ThisTy->isPointerOrReferenceType())
+ ThisTy = ThisTy->getPointeeType();
+ if (!ThisTy->getAsCXXRecordDecl()) {
+ S.Diag(ThisArg->getExprLoc(), diag::err_virtual_member_lhs_cxxrec);
+ return ExprError();
+ }
+
+ const Expr *MemFunArg = Call->getArg(1);
+ APValue Result;
+ if (!MemFunArg->isCXX11ConstantExpr(S.getASTContext(), &Result, nullptr)) {
+ S.Diag(MemFunArg->getExprLoc(), diag::err_virtual_member_addrof);
+ return ExprError();
+ }
+
+ if (!Result.isMemberPointer() ||
+ !isa<CXXMethodDecl>(Result.getMemberPointerDecl())) {
+ S.Diag(MemFunArg->getExprLoc(), diag::err_virtual_member_addrof);
+ return ExprError();
+ }
+
+ const CXXMethodDecl *CXXMethod =
+ cast<CXXMethodDecl>(Result.getMemberPointerDecl());
+ if (!CXXMethod->isVirtual()) {
+ S.Diag(MemFunArg->getExprLoc(), diag::err_virtual_member_addrof);
+ return ExprError();
+ }
+
+ if (ThisTy->getAsCXXRecordDecl() != CXXMethod->getParent() &&
+ !S.IsDerivedFrom(Call->getBeginLoc(), ThisTy,
+ CXXMethod->getFunctionObjectParameterType())) {
+ S.Diag(ThisArg->getExprLoc(), diag::err_virtual_member_inherit);
+ return ExprError();
+ }
+ return Call;
+}
+
+static ExprResult GetVTablePointer(Sema &S, CallExpr *Call) {
+ if (S.checkArgCount(Call, 1))
+ return ExprError();
+ ExprResult ThisArg = S.DefaultFunctionArrayLvalueConversion(Call->getArg(0));
+ if (ThisArg.isInvalid())
+ return ExprError();
+ Call->setArg(0, ThisArg.get());
+ const Expr *Subject = Call->getArg(0);
+ QualType SubjectType = Subject->getType();
+ if (SubjectType->isPointerOrReferenceType())
----------------
ojhunt wrote:
Will be reverting this to require a pointer arg
https://github.com/llvm/llvm-project/pull/135469
More information about the cfe-commits
mailing list