|
26 | 26 | using namespace llvm;
|
27 | 27 | using namespace clang;
|
28 | 28 |
|
| 29 | + |
| 30 | +// Check if the compound statement is a function body |
| 31 | +// Used in both visitors so abstracted to a function |
| 32 | +bool isTopLevel(ASTContext *Context, CompoundStmt *S) { |
| 33 | + const auto &Parents = Context->getParents(*S); |
| 34 | + if (Parents.empty()) { |
| 35 | + return false; |
| 36 | + } |
| 37 | + // Ensure that our parent is a functiondecl |
| 38 | + return Parents[0].get<FunctionDecl>() != nullptr; |
| 39 | +} |
| 40 | + |
29 | 41 | // CheckedRegionAdder
|
30 | 42 |
|
31 | 43 | bool CheckedRegionAdder::VisitCompoundStmt(CompoundStmt *S) {
|
@@ -92,12 +104,10 @@ CheckedRegionAdder::findParentCompound(const ast_type_traits::DynTypedNode &N,
|
92 | 104 | return *Min;
|
93 | 105 | }
|
94 | 106 |
|
| 107 | + |
| 108 | + |
95 | 109 | bool CheckedRegionAdder::isFunctionBody(CompoundStmt *S) {
|
96 |
| - const auto &Parents = Context->getParents(*S); |
97 |
| - if (Parents.empty()) { |
98 |
| - return false; |
99 |
| - } |
100 |
| - return Parents[0].get<FunctionDecl>(); |
| 110 | + return isTopLevel(Context, S); |
101 | 111 | }
|
102 | 112 |
|
103 | 113 | bool CheckedRegionAdder::isParentChecked(
|
@@ -154,13 +164,26 @@ bool CheckedRegionFinder::VisitDoStmt(DoStmt *S) {
|
154 | 164 |
|
155 | 165 | bool CheckedRegionFinder::VisitCompoundStmt(CompoundStmt *S) {
|
156 | 166 | // Visit all subblocks, find all unchecked types
|
157 |
| - bool Localwild = 0; |
| 167 | + bool Localwild = false; |
158 | 168 | for (const auto &SubStmt : S->children()) {
|
159 | 169 | CheckedRegionFinder Sub(Context, Writer, Info, Seen, Map, EmitWarnings);
|
160 | 170 | Sub.TraverseStmt(SubStmt);
|
161 | 171 | Localwild |= Sub.Wild;
|
162 | 172 | }
|
163 | 173 |
|
| 174 | + // If we are a function def, need to check return type |
| 175 | + if (isTopLevel(Context, S)) { |
| 176 | + const auto &Parents = Context->getParents(*S); |
| 177 | + assert(!Parents.empty()); |
| 178 | + FunctionDecl* Parent = const_cast<FunctionDecl*>(Parents[0].get<FunctionDecl>()); |
| 179 | + assert(Parent != nullptr); |
| 180 | + auto retType = Parent->getReturnType().getTypePtr(); |
| 181 | + if (retType->isPointerType()) { |
| 182 | + CVarOption CV = Info.getVariable(Parent, Context); |
| 183 | + Localwild |= isWild(CV) || containsUncheckedPtr(Parent->getReturnType()); |
| 184 | + } |
| 185 | + } |
| 186 | + |
164 | 187 | markChecked(S, Localwild);
|
165 | 188 |
|
166 | 189 | Wild = false;
|
|
0 commit comments