Skip to content

Commit b50aa39

Browse files
committed
[CHERIoT] Support most operations on __sealed_capabilities in unevaluated contexts.
This is needed in order to support things like sizeof and decltype. Casts to an from sealed types are still disallowed.
1 parent b3e304a commit b50aa39

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5192,7 +5192,8 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
51925192
}
51935193

51945194
// No subscripting allowed on sealed pointers.
5195-
if (base->getType()->isCHERISealedCapabilityType(Context))
5195+
if (base->getType()->isCHERISealedCapabilityType(Context) &&
5196+
!isUnevaluatedContext())
51965197
Diag(lbLoc, diag::err_sealed_bad_operator) << base->getType();
51975198

51985199
// Handle any non-overload placeholder types in the base and index
@@ -7370,7 +7371,8 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
73707371
Fn = result.get();
73717372
}
73727373

7373-
if (Fn->getType()->isCHERISealedCapabilityType(Context))
7374+
if (Fn->getType()->isCHERISealedCapabilityType(Context) &&
7375+
!isUnevaluatedContext())
73747376
return ExprError(Diag(Fn->getBeginLoc(), diag::err_sealed_func_pointer)
73757377
<< Fn->getType());
73767378

@@ -12113,7 +12115,8 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
1211312115
Expr *PExp = LHS.get(), *IExp = RHS.get();
1211412116

1211512117
// Addition is not allowed on sealed pointers.
12116-
if (PExp->getType()->isCHERISealedCapabilityType(Context))
12118+
if (PExp->getType()->isCHERISealedCapabilityType(Context) &&
12119+
!isUnevaluatedContext())
1211712120
return InvalidOperands(Loc, LHS, RHS);
1211812121

1211912122
bool isObjCPointer;
@@ -12228,10 +12231,12 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
1222812231
QualType lpointee = LHS.get()->getType()->getPointeeType();
1222912232

1223012233
// Subtraction is not allowed on sealed pointers.
12231-
if (LHS.get()->getType()->isCHERISealedCapabilityType(Context))
12232-
return InvalidOperands(Loc, LHS, RHS);
12233-
if (RHS.get()->getType()->isCHERISealedCapabilityType(Context))
12234-
return InvalidOperands(Loc, LHS, RHS);
12234+
if (!isUnevaluatedContext()) {
12235+
if (LHS.get()->getType()->isCHERISealedCapabilityType(Context))
12236+
return InvalidOperands(Loc, LHS, RHS);
12237+
if (RHS.get()->getType()->isCHERISealedCapabilityType(Context))
12238+
return InvalidOperands(Loc, LHS, RHS);
12239+
}
1223512240

1223612241
// Diagnose bad cases where we step over interface counts.
1223712242
if (LHS.get()->getType()->isObjCObjectPointerType() &&
@@ -16608,7 +16613,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
1660816613
// The only unary operator that can apply to a sealed capability is AddrOf.
1660916614
auto *PtrInput = InputExpr->getType()->getAs<PointerType>();
1661016615
if (Opc != UO_AddrOf && PtrInput &&
16611-
InputExpr->getType()->isCHERISealedCapabilityType(Context))
16616+
InputExpr->getType()->isCHERISealedCapabilityType(Context) &&
16617+
!isUnevaluatedContext())
1661216618
Diag(OpLoc, diag::err_sealed_bad_operator) << InputExpr->getType();
1661316619

1661416620
switch (Opc) {

clang/lib/Sema/SemaExprMember.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
792792
LookupResult R(*this, NameInfo, LookupMemberName);
793793

794794
// Member accesses are not allowed on sealed capabilities.
795-
if (BaseType->isCHERISealedCapabilityType(Context))
795+
if (BaseType->isCHERISealedCapabilityType(Context) && !isUnevaluatedContext())
796796
return ExprError(Diag(OpLoc, diag::err_sealed_member_access) << BaseType);
797797

798798
// Implicit member accesses.

clang/test/Sema/cheri/attr-cheriot-sealed.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ void test11(int * __sealed_capability x) {
5252
opaque(x); // No error (cast to void permitted)
5353
}
5454

55+
int test12(int * __sealed_capability a) {
56+
return sizeof(*a);
57+
}

clang/test/SemaCXX/cheri/attr-cheriot-sealed.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,10 @@ int test6(int * __sealed_capability b) {
3939
test_struct3 c{b}; // expected-error{{converting sealed type 'int * __sealed_capability' to non-sealed type 'int *' without an explicit unsealing}}
4040
return *(c.a);
4141
}
42+
43+
int test11(int * __sealed_capability a) {
44+
int b = 42;
45+
decltype(*a) c = b;
46+
c = 43;
47+
return b;
48+
}

0 commit comments

Comments
 (0)