Skip to content

Commit dc20a8a

Browse files
eupharinaresistor
authored andcommitted
[CHERI_CSA] AllocationChecker: suppress for ptr to first field
1 parent b926eed commit dc20a8a

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
@@ -93,21 +93,32 @@ bool relatedTypes(const Type *Ty1, const Type *Ty2) {
9393
return true;
9494
if (Ty1->isArrayType())
9595
return relatedTypes(Ty1->getArrayElementTypeNoTypeQual(), Ty2);
96+
if (Ty1->isRecordType()) {
97+
if (RecordDecl *RD = Ty1->getAs<RecordType>()->getAsRecordDecl()) {
98+
const RecordDecl::field_iterator &FirstField = RD->field_begin();
99+
if (FirstField != RD->field_end()) {
100+
const Type *FFTy = FirstField->getType()->getUnqualifiedDesugaredType();
101+
return relatedTypes(FFTy, Ty2);
102+
}
103+
}
104+
}
96105
return false;
97106
}
98107

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

105116
std::optional<QualType> getPrevType(ProgramStateRef State, const MemRegion *R) {
106117
if (const QualType *PrevTy = State->get<AllocMap>(R))
107118
return *PrevTy;
108119
if (const TypedValueRegion *TR = R->getAs<TypedValueRegion>()) {
109120
QualType Ty = TR->getValueType();
110-
if ((Ty->isPointerType() || Ty->isArrayType()) && !isGenPtrType(Ty))
121+
if (reportForType(Ty))
111122
return Ty;
112123
}
113124
return std::nullopt;
@@ -170,9 +181,7 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
170181
}
171182

172183
QualType DstTy = CE->getType().getUnqualifiedType();
173-
if (!DstTy->isPointerType())
174-
return;
175-
if (DstTy->isVoidPointerType() || DstTy->getPointeeType()->isCharType())
184+
if (!reportForType(DstTy))
176185
return;
177186

178187
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)