@@ -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
104115std::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);
0 commit comments