@@ -704,6 +704,12 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
704704 QualType T = E->getType();
705705 assert(!T.isNull() && "r-value conversion on typeless expression?");
706706
707+ // CHERIoT-specific check.
708+ if (T.hasCHERIoTSealedAttr() && !isUnevaluatedContext()) {
709+ return ExprError(
710+ Diag(E->getExprLoc(), diag::err_cheriot_non_addr_of_expr_on_sealed));
711+ }
712+
707713 // lvalue-to-rvalue conversion cannot be applied to types that decay to
708714 // pointers (i.e. function or array types).
709715 if (T->canDecayToPointerType())
@@ -4906,6 +4912,11 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
49064912 MultiExprArg ArgExprs,
49074913 SourceLocation rbLoc) {
49084914
4915+ // CHERIoT-specific check.
4916+ if (base->getType().hasCHERIoTSealedAttr() && !isUnevaluatedContext()) {
4917+ return ExprError(Diag(lbLoc, diag::err_cheriot_non_addr_of_expr_on_sealed));
4918+ }
4919+
49094920 if (base && !base->getType().isNull() &&
49104921 base->hasPlaceholderType(BuiltinType::ArraySection)) {
49114922 auto *AS = cast<ArraySectionExpr>(base);
@@ -8535,6 +8546,21 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
85358546 ExprObjectKind &OK,
85368547 SourceLocation QuestionLoc) {
85378548
8549+ // CHERIoT-specific check.
8550+ if (!isUnevaluatedContext()) {
8551+ if (LHS.get()->getType().hasCHERIoTSealedAttr()) {
8552+ Diag(LHS.get()->getExprLoc(),
8553+ diag::err_cheriot_non_addr_of_expr_on_sealed);
8554+ return QualType();
8555+ }
8556+
8557+ if (RHS.get()->getType().hasCHERIoTSealedAttr()) {
8558+ Diag(RHS.get()->getExprLoc(),
8559+ diag::err_cheriot_non_addr_of_expr_on_sealed);
8560+ return QualType();
8561+ }
8562+ }
8563+
85388564 ExprResult LHSResult = CheckPlaceholderExpr(LHS.get());
85398565 if (!LHSResult.isUsable()) return QualType();
85408566 LHS = LHSResult;
@@ -14717,6 +14743,9 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
1471714743 CheckAddressOfPackedMember(op);
1471814744
1471914745 PointerInterpretationKind PIK = PointerInterpretationForBaseExpr(op);
14746+ if (op->getType().hasCHERIoTSealedAttr()) {
14747+ PIK = PIK_SealedCapability;
14748+ }
1472014749 return Context.getPointerType(op->getType(), PIK);
1472114750}
1472214751
@@ -15659,6 +15688,19 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
1565915688 LHSExpr = LHS.get();
1566015689 RHSExpr = RHS.get();
1566115690
15691+ // CHERIoT-specific check.
15692+ if (!isUnevaluatedContext()) {
15693+ if (LHSExpr->getType().hasCHERIoTSealedAttr()) {
15694+ return ExprError(Diag(LHS.get()->getExprLoc(),
15695+ diag::err_cheriot_non_addr_of_expr_on_sealed));
15696+ }
15697+
15698+ if (RHSExpr->getType().hasCHERIoTSealedAttr()) {
15699+ return ExprError(Diag(RHS.get()->getExprLoc(),
15700+ diag::err_cheriot_non_addr_of_expr_on_sealed));
15701+ }
15702+ }
15703+
1566215704 // We want to end up calling one of SemaPseudoObject::checkAssignment
1566315705 // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if
1566415706 // both expressions are overloadable or either is type-dependent),
@@ -16097,6 +16139,12 @@ bool Sema::isQualifiedMemberAccess(Expr *E) {
1609716139ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
1609816140 UnaryOperatorKind Opc, Expr *Input,
1609916141 bool IsAfterAmp) {
16142+ // CHERIoT-specific check.
16143+ if (Input->getType().hasCHERIoTSealedAttr() && (Opc != UO_AddrOf) &&
16144+ !isUnevaluatedContext()) {
16145+ return ExprError(Diag(OpLoc, diag::err_cheriot_non_addr_of_expr_on_sealed));
16146+ }
16147+
1610016148 // First things first: handle placeholders so that the
1610116149 // overloaded-operator check considers the right type.
1610216150 if (const BuiltinType *pty = Input->getType()->getAsPlaceholderType()) {
0 commit comments