clang: lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17#include

18

20

23}

24

26 const Expr *E, bool StopAtFirstRefCountedObj,

27 std::function<bool(const clang::Expr *, bool)> callback) {

28 while (E) {

29 if (auto *tempExpr = dyn_cast(E)) {

30 E = tempExpr->getSubExpr();

31 continue;

32 }

33 if (auto *tempExpr = dyn_cast(E)) {

34 E = tempExpr->getSubExpr();

35 continue;

36 }

37 if (auto *tempExpr = dyn_cast(E)) {

38 if (auto *C = tempExpr->getConstructor()) {

40 return callback(E, true);

41 break;

42 }

43 }

44 if (auto *POE = dyn_cast(E)) {

45 if (auto *RF = POE->getResultExpr()) {

46 E = RF;

47 continue;

48 }

49 }

50 if (auto *tempExpr = dyn_cast(E)) {

51 E = tempExpr->getSubExpr();

52 continue;

53 }

54 if (auto *Expr = dyn_cast(E)) {

56 callback) &&

58 callback);

59 }

60 if (auto *cast = dyn_cast(E)) {

61 if (StopAtFirstRefCountedObj) {

62 if (auto *ConversionFunc =

63 dyn_cast_or_null(cast->getConversionFunction())) {

65 return callback(E, true);

66 }

67 }

68

69

70 E = cast->getSubExpr();

71 continue;

72 }

73 if (auto *call = dyn_cast(E)) {

74 if (auto *memberCall = dyn_cast(call)) {

75 if (auto *decl = memberCall->getMethodDecl()) {

77 if (IsGetterOfRefCt && *IsGetterOfRefCt) {

78 E = memberCall->getImplicitObjectArgument();

79 if (StopAtFirstRefCountedObj) {

80 return callback(E, true);

81 }

82 continue;

83 }

84 }

85 }

86

87 if (auto *operatorCall = dyn_cast(E)) {

88 if (operatorCall->getNumArgs() == 1) {

89 E = operatorCall->getArg(0);

90 continue;

91 }

92 }

93

94 if (auto *callee = call->getDirectCallee()) {

96 if (StopAtFirstRefCountedObj)

97 return callback(E, true);

98

99 E = call->getArg(0);

100 continue;

101 }

102

104 return callback(E, true);

105

107 return callback(E, true);

108

109 if (callee->isInStdNamespace() && safeGetName(callee) == "forward") {

110 E = call->getArg(0);

111 continue;

112 }

113

115 E = call->getArg(0);

116 continue;

117 }

118 }

119 }

120 if (auto *ObjCMsgExpr = dyn_cast(E)) {

121 if (auto *Method = ObjCMsgExpr->getMethodDecl()) {

123 return callback(E, true);

124 }

125 }

126 if (auto *unaryOp = dyn_cast(E)) {

127

128 E = unaryOp->getSubExpr();

129 continue;

130 }

131

132 break;

133 }

134

135 return callback(E, false);

136}

137

139 assert(E);

140 if (auto *Ref = dyn_cast(E)) {

141 if (auto *D = dyn_cast_or_null(Ref->getFoundDecl())) {

142 if (isa(D) || D->isLocalVarDecl())

143 return true;

144 }

145 }

147 return true;

148

149

150 return isa(E);

151}

152

154 if (auto *MCE = dyn_cast(E)) {

155 if (auto *Callee = MCE->getDirectCallee()) {

157 if (Name == "get" || Name == "ptr") {

158 auto *ThisArg = MCE->getImplicitObjectArgument();

159 E = ThisArg;

160 }

161 }

162 } else if (auto *OCE = dyn_cast(E)) {

163 if (OCE->getOperator() == OO_Star && OCE->getNumArgs() == 1)

164 E = OCE->getArg(0);

165 }

166 auto *ME = dyn_cast(E);

167 if (!ME)

168 return false;

169 auto *D = ME->getMemberDecl();

170 if (D)

171 return false;

172 auto T = D->getType();

174}

175

178public:

180 for (const Stmt *Child : S->children()) {

181 if (Child && Visit(Child))

182 return false;

183 }

184 return true;

185 }

186

189 RV = RV->IgnoreParenCasts();

190 if (isa(RV))

191 return true;

193 }

194 return false;

195 }

196};

197

199 auto *MCE = dyn_cast(E);

200 if (!MCE)

201 return false;

202 auto *Callee = MCE->getDirectCallee();

203 if (!Callee)

204 return false;

205 auto *Body = Callee->getBody();

206 if (!Body)

207 return false;

208 auto [CacheIt, IsNew] = Cache.insert(std::make_pair(Callee, false));

209 if (IsNew)

211 return CacheIt->second;

212}

213

214}

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

Represents a C++ struct/union/class.

ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.

Decl - This represents one declaration (or definition), e.g.

bool isACallToEnsureFn(const Expr *E) const

bool VisitReturnStmt(const ReturnStmt *RS)

bool VisitStmt(const Stmt *S)

This represents one expression.

ReturnStmt - This represents a return, optionally of an expression: return; return 4;.

RetTy Visit(PTR(Stmt) S, ParamTys... P)

Stmt - This represents one statement.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

The JSON file list parser is used to communicate input to InstallAPI.

bool isCtorOfSafePtr(const clang::FunctionDecl *F)

bool isPtrConversion(const FunctionDecl *F)

bool isCtorOfRefCounted(const clang::FunctionDecl *F)

bool isASafeCallArg(const Expr *E)

For E referring to a ref-countable/-counted pointer/reference we return whether it's a safe call argu...

bool isSingleton(const FunctionDecl *F)

bool isRefCounted(const CXXRecordDecl *R)

bool isOwnerPtrType(const clang::QualType T)

bool isSafePtrType(const clang::QualType T)

std::optional< bool > isGetterOfSafePtr(const CXXMethodDecl *M)

const FunctionProtoType * T

bool isSafePtr(clang::CXXRecordDecl *Decl)

bool tryToFindPtrOrigin(const Expr *E, bool StopAtFirstRefCountedObj, std::function< bool(const clang::Expr *, bool)> callback)

This function de-facto defines a set of transformations that we consider safe (in heuristical sense).

std::string safeGetName(const T *ASTNode)

bool isCtorOfCheckedPtr(const clang::FunctionDecl *F)

bool isCheckedPtr(const std::string &Name)

U cast(CodeGen::Address addr)

@ Class

The "class" keyword introduces the elaborated-type-specifier.

bool isConstOwnerPtrMemberExpr(const clang::Expr *E)