@@ -200,6 +200,7 @@ class GCChecker
200
200
const MemRegion *Region);
201
201
202
202
static bool isGCTrackedType (QualType Type);
203
+ static bool isGCTracked (const Expr *E);
203
204
bool isGloballyRootedType (QualType Type) const ;
204
205
static void dumpState (const ProgramStateRef &State);
205
206
static bool declHasAnnotation (const clang::Decl *D, const char *which);
@@ -703,12 +704,8 @@ void GCChecker::checkBeginFunction(CheckerContext &C) const {
703
704
}
704
705
}
705
706
706
- #if LLVM_VERSION_MAJOR >= 7
707
707
void GCChecker::checkEndFunction (const clang::ReturnStmt *RS,
708
708
CheckerContext &C) const {
709
- #else
710
- void GCChecker::checkEndFunction (CheckerContext &C) const {
711
- #endif
712
709
ProgramStateRef State = C.getState ();
713
710
bool Changed = false ;
714
711
if (State->get <GCDisabledAt>() == C.getStackFrame ()->getIndex ()) {
@@ -789,6 +786,19 @@ bool GCChecker::isGCTrackedType(QualType QT) {
789
786
QT);
790
787
}
791
788
789
+ bool GCChecker::isGCTracked (const Expr *E) {
790
+ while (1 ) {
791
+ if (isGCTrackedType (E->getType ()))
792
+ return true ;
793
+ if (auto ICE = dyn_cast<ImplicitCastExpr>(E))
794
+ E = ICE->getSubExpr ();
795
+ else if (auto CE = dyn_cast<CastExpr>(E))
796
+ E = CE->getSubExpr ();
797
+ else
798
+ return false ;
799
+ }
800
+ }
801
+
792
802
bool GCChecker::isGloballyRootedType (QualType QT) const {
793
803
return isJuliaType (
794
804
[](StringRef Name) { return Name.endswith_lower (" jl_sym_t" ); }, QT);
@@ -1053,7 +1063,7 @@ SymbolRef GCChecker::getSymbolForResult(const Expr *Result,
1053
1063
QualType QT = Result->getType ();
1054
1064
if (!QT->isPointerType ())
1055
1065
return nullptr ;
1056
- if (OldValS || GCChecker::isGCTrackedType (QT )) {
1066
+ if (OldValS || GCChecker::isGCTracked (Result )) {
1057
1067
Loaded = C.getSValBuilder ().conjureSymbolVal (
1058
1068
nullptr , Result, C.getLocationContext (), Result->getType (),
1059
1069
C.blockCount ());
@@ -1082,7 +1092,7 @@ void GCChecker::checkDerivingExpr(const Expr *Result, const Expr *Parent,
1082
1092
State->set <GCValueMap>(NewSym, ValueState::getRooted (nullptr , -1 )));
1083
1093
return ;
1084
1094
}
1085
- if (!isGCTrackedType (Result-> getType () )) {
1095
+ if (!isGCTracked (Result)) {
1086
1096
// TODO: We may want to refine this. This is to track pointers through the
1087
1097
// array list in jl_module_t.
1088
1098
bool ParentIsModule = isJuliaType (
@@ -1091,8 +1101,7 @@ void GCChecker::checkDerivingExpr(const Expr *Result, const Expr *Parent,
1091
1101
bool ResultIsArrayList = isJuliaType (
1092
1102
[](StringRef Name) { return Name.endswith_lower (" arraylist_t" ); },
1093
1103
Result->getType ());
1094
- if (!(ParentIsModule && ResultIsArrayList) &&
1095
- isGCTrackedType (Parent->getType ())) {
1104
+ if (!(ParentIsModule && ResultIsArrayList) && isGCTracked (Parent)) {
1096
1105
ResultTracked = false ;
1097
1106
}
1098
1107
}
@@ -1144,7 +1153,7 @@ void GCChecker::checkDerivingExpr(const Expr *Result, const Expr *Parent,
1144
1153
}
1145
1154
if (!OldValS) {
1146
1155
// This way we'll get better diagnostics
1147
- if (isGCTrackedType (Result-> getType () )) {
1156
+ if (isGCTracked (Result)) {
1148
1157
C.addTransition (
1149
1158
State->set <GCValueMap>(NewSym, ValueState::getUntracked ()));
1150
1159
}
@@ -1167,8 +1176,7 @@ void GCChecker::checkPostStmt(const ArraySubscriptExpr *ASE,
1167
1176
const MemRegion *Region = C.getSVal (ASE->getLHS ()).getAsRegion ();
1168
1177
ProgramStateRef State = C.getState ();
1169
1178
SValExplainer Ex (C.getASTContext ());
1170
- if (Region && Region->getAs <ElementRegion>() &&
1171
- isGCTrackedType (ASE->getType ())) {
1179
+ if (Region && Region->getAs <ElementRegion>() && isGCTracked (ASE)) {
1172
1180
const RootState *RS =
1173
1181
State->get <GCRootMap>(Region->getAs <ElementRegion>()->getSuperRegion ());
1174
1182
if (RS) {
@@ -1192,7 +1200,7 @@ void GCChecker::checkPostStmt(const MemberExpr *ME, CheckerContext &C) const {
1192
1200
// It is possible for the member itself to be gcrooted, so check that first
1193
1201
const MemRegion *Region = C.getSVal (ME).getAsRegion ();
1194
1202
ProgramStateRef State = C.getState ();
1195
- if (Region && isGCTrackedType (ME-> getType () )) {
1203
+ if (Region && isGCTracked (ME)) {
1196
1204
if (const RootState *RS = State->get <GCRootMap>(Region)) {
1197
1205
ValueState ValS = ValueState::getRooted (Region, RS->RootedAtDepth );
1198
1206
SymbolRef NewSym = getSymbolForResult (ME, &ValS, State, C);
@@ -1274,7 +1282,7 @@ void GCChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
1274
1282
SourceRange range;
1275
1283
if (const Expr *E = Call.getArgExpr (idx)) {
1276
1284
range = E->getSourceRange ();
1277
- if (!isGCTrackedType (E-> getType () ))
1285
+ if (!isGCTracked (E ))
1278
1286
continue ;
1279
1287
}
1280
1288
if (ValState->isPotentiallyFreed ()) {
0 commit comments