diff --git a/clang/lib/3C/CheckedRegions.cpp b/clang/lib/3C/CheckedRegions.cpp index 6c9ce210b7d3..aeb4c40d3532 100644 --- a/clang/lib/3C/CheckedRegions.cpp +++ b/clang/lib/3C/CheckedRegions.cpp @@ -26,6 +26,18 @@ using namespace llvm; using namespace clang; + +// Check if the compound statement is a function body +// Used in both visitors so abstracted to a function +bool isTopLevel(ASTContext *Context, CompoundStmt *S) { + const auto &Parents = Context->getParents(*S); + if (Parents.empty()) { + return false; + } + // Ensure that our parent is a functiondecl + return Parents[0].get() != nullptr; +} + // CheckedRegionAdder bool CheckedRegionAdder::VisitCompoundStmt(CompoundStmt *S) { @@ -92,12 +104,10 @@ CheckedRegionAdder::findParentCompound(const ast_type_traits::DynTypedNode &N, return *Min; } + + bool CheckedRegionAdder::isFunctionBody(CompoundStmt *S) { - const auto &Parents = Context->getParents(*S); - if (Parents.empty()) { - return false; - } - return Parents[0].get(); + return isTopLevel(Context, S); } bool CheckedRegionAdder::isParentChecked( @@ -154,13 +164,26 @@ bool CheckedRegionFinder::VisitDoStmt(DoStmt *S) { bool CheckedRegionFinder::VisitCompoundStmt(CompoundStmt *S) { // Visit all subblocks, find all unchecked types - bool Localwild = 0; + bool Localwild = false; for (const auto &SubStmt : S->children()) { CheckedRegionFinder Sub(Context, Writer, Info, Seen, Map, EmitWarnings); Sub.TraverseStmt(SubStmt); Localwild |= Sub.Wild; } + // If we are a function def, need to check return type + if (isTopLevel(Context, S)) { + const auto &Parents = Context->getParents(*S); + assert(!Parents.empty()); + FunctionDecl* Parent = const_cast(Parents[0].get()); + assert(Parent != nullptr); + auto retType = Parent->getReturnType().getTypePtr(); + if (retType->isPointerType()) { + CVarOption CV = Info.getVariable(Parent, Context); + Localwild |= isWild(CV) || containsUncheckedPtr(Parent->getReturnType()); + } + } + markChecked(S, Localwild); Wild = false; diff --git a/clang/test/3C/checkedregions.c b/clang/test/3C/checkedregions.c index 8b3f1700bd8a..992ac010445f 100644 --- a/clang/test/3C/checkedregions.c +++ b/clang/test/3C/checkedregions.c @@ -80,3 +80,10 @@ void baz(void) { bad(); } } + +int* g() { + //CHECK: int* g(void) { + return 1; +} + + diff --git a/clang/test/3C/fn_sets.c b/clang/test/3C/fn_sets.c index e3c03273d137..036919d4eeac 100644 --- a/clang/test/3C/fn_sets.c +++ b/clang/test/3C/fn_sets.c @@ -51,19 +51,19 @@ void foo1(int *z) { /* Testing Something with a larger set of functions */ int *a() { - //CHECK: int *a(void) _Checked { + //CHECK: int *a(void) { return 0; } int *b() { - //CHECK: int *b(void) _Checked { + //CHECK: int *b(void) { return 0; } int *c() { - //CHECK: int *c(void) _Checked { + //CHECK: int *c(void) { return 0; } int *d() { - //CHECK: int *d(void) _Checked { + //CHECK: int *d(void) { return 0; } int *e() { @@ -72,7 +72,7 @@ int *e() { //CHECK: return (int*) 1; } int *i() { - //CHECK: _Ptr i(void) _Checked { + //CHECK: _Ptr i(void) _Checked { return 0; }