Skip to content

Commit 403db5a

Browse files
eupharinaresistor
authored andcommitted
[CHERI_CSA] AllocationChecker: suppress for ptr to first field
1 parent 14ba468 commit 403db5a

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

clang/lib/StaticAnalyzer/Checkers/CHERI/AllocationChecker.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,32 @@ bool relatedTypes(const Type *Ty1, const Type *Ty2) {
9292
return true;
9393
if (Ty1->isArrayType())
9494
return relatedTypes(Ty1->getArrayElementTypeNoTypeQual(), Ty2);
95+
if (Ty1->isRecordType()) {
96+
if (RecordDecl *RD = Ty1->getAs<RecordType>()->getAsRecordDecl()) {
97+
const RecordDecl::field_iterator &FirstField = RD->field_begin();
98+
if (FirstField != RD->field_end()) {
99+
const Type *FFTy = FirstField->getType()->getUnqualifiedDesugaredType();
100+
return relatedTypes(FFTy, Ty2);
101+
}
102+
}
103+
}
95104
return false;
96105
}
97106

98-
bool isGenPtrType(QualType Ty) {
99-
return Ty->isVoidPointerType() ||
100-
((Ty->isPointerType() || Ty->isArrayType()) &&
101-
Ty->getPointeeOrArrayElementType()->isCharType());
107+
bool reportForType(QualType Ty) {
108+
if (Ty->isVoidPointerType())
109+
return false;
110+
if (Ty->isPointerType() || Ty->isArrayType())
111+
return !Ty->getPointeeOrArrayElementType()->isCharType();
112+
return false;
102113
}
103114

104115
std::optional<QualType> getPrevType(ProgramStateRef State, const MemRegion *R) {
105116
if (const QualType *PrevTy = State->get<AllocMap>(R))
106117
return *PrevTy;
107118
if (const TypedValueRegion *TR = R->getAs<TypedValueRegion>()) {
108119
QualType Ty = TR->getValueType();
109-
if ((Ty->isPointerType() || Ty->isArrayType()) && !isGenPtrType(Ty))
120+
if (reportForType(Ty))
110121
return Ty;
111122
}
112123
return std::nullopt;
@@ -169,9 +180,7 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
169180
}
170181

171182
QualType DstTy = CE->getType().getUnqualifiedType();
172-
if (!DstTy->isPointerType())
173-
return;
174-
if (DstTy->isVoidPointerType() || DstTy->getPointeeType()->isCharType())
183+
if (!reportForType(DstTy))
175184
return;
176185

177186
std::optional<QualType> PrevTy = getPrevType(State, SR);

clang/test/Analysis/Checkers/CHERI/allocation.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@ struct S2 * test_2(int n1) {
2828
return p2;
2929
}
3030

31-
int * test_3(int n1, int n2) {
32-
void *p1 = malloc(sizeof(struct S1)*n1 + sizeof(struct S2)*n2);
33-
struct S2 *p2 = (struct S2 *)(p1+n1);
34-
int *p3 = (int*)(p2 + n2); // expected-warning{{Allocation partition}}
35-
return p3;
31+
struct S2 * test_3(int n1, int n2) {
32+
struct S1 *p1 = malloc(sizeof(struct S1)*n1 + sizeof(struct S2)*n2);
33+
struct S2 *p2 = (struct S2 *)(p1+n1); // expected-warning{{Allocation partition}}
34+
return p2;
3635
}
3736

3837
void array(int i, int j) {
@@ -41,3 +40,14 @@ void array(int i, int j) {
4140
int *p2 = p1[j]; // no warn
4241
*p2 = 42;
4342
}
43+
44+
struct S3 {
45+
struct S2 s2;
46+
int y;
47+
};
48+
49+
struct S2 * first_field(void *p, int n1) {
50+
struct S3 *p3 = p;
51+
struct S2 *p2 = (struct S2 *)(p3+n1); // no warn
52+
return p2;
53+
}

0 commit comments

Comments
 (0)