]> granicus.if.org Git - clang/commitdiff
Hoist diagnostic generation in ReturnStackAddressChecker into a separate method....
authorTed Kremenek <kremenek@apple.com>
Tue, 2 Feb 2010 00:13:41 +0000 (00:13 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 2 Feb 2010 00:13:41 +0000 (00:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95037 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Checker/ReturnStackAddressChecker.cpp

index 04935f94782bb99da8cf8554a504588be5a791d8..9cbabba4a5f5c54d9ee950ed65231e387e00273d 100644 (file)
@@ -27,9 +27,11 @@ class ReturnStackAddressChecker :
     public CheckerVisitor<ReturnStackAddressChecker> {      
   BuiltinBug *BT;
 public:
-    ReturnStackAddressChecker() : BT(0) {}
-    static void *getTag();
-    void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
+  ReturnStackAddressChecker() : BT(0) {}
+  static void *getTag();
+  void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
+private:
+  void EmitStackError(CheckerContext &C, const MemRegion *R, const Expr *RetE);
 };
 }
 
@@ -41,6 +43,68 @@ void *ReturnStackAddressChecker::getTag() {
   static int x = 0; return &x;
 }
 
+void ReturnStackAddressChecker::EmitStackError(CheckerContext &C,
+                                               const MemRegion *R,
+                                               const Expr *RetE) {
+       ExplodedNode *N = C.GenerateSink();
+
+       if (!N)
+               return;
+
+       if (!BT)
+               BT = new BuiltinBug("Return of address to stack-allocated memory");
+
+       // Generate a report for this bug.
+       llvm::SmallString<512> buf;
+       llvm::raw_svector_ostream os(buf);
+       SourceRange range;
+
+       // Get the base region, stripping away fields and elements.
+       R = R->getBaseRegion();
+
+       // Check if the region is a compound literal.
+       if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) {    
+               const CompoundLiteralExpr* CL = CR->getLiteralExpr();
+               os << "Address of stack memory associated with a compound literal "
+          "declared on line "
+       << C.getSourceManager().getInstantiationLineNumber(CL->getLocStart())
+       << " returned to caller";    
+               range = CL->getSourceRange();
+       }
+       else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(R)) {
+               const Expr* ARE = AR->getExpr();
+               SourceLocation L = ARE->getLocStart();
+               range = ARE->getSourceRange();    
+               os << "Address of stack memory allocated by call to alloca() on line "
+       << C.getSourceManager().getInstantiationLineNumber(L)
+       << " returned to caller";
+       }
+       else if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
+               const BlockDecl *BD = BR->getCodeRegion()->getDecl();
+               SourceLocation L = BD->getLocStart();
+               range = BD->getSourceRange();
+               os << "Address of stack-allocated block declared on line "
+       << C.getSourceManager().getInstantiationLineNumber(L)
+       << " returned to caller";
+       }
+       else if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
+               os << "Address of stack memory associated with local variable '"
+       << VR->getString() << "' returned";
+               range = VR->getDecl()->getSourceRange();
+       }
+       else {
+               assert(false && "Invalid region in ReturnStackAddressChecker.");
+               return;
+       }
+
+       RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
+       report->addRange(RetE->getSourceRange());
+       if (range.isValid())
+               report->addRange(range);
+
+       C.EmitReport(report);
+}      
+
 void ReturnStackAddressChecker::PreVisitReturnStmt(CheckerContext &C,
                                                    const ReturnStmt *RS) {
   
@@ -54,61 +118,8 @@ void ReturnStackAddressChecker::PreVisitReturnStmt(CheckerContext &C,
   if (!R || !R->hasStackStorage())
     return;  
   
-  ExplodedNode *N = C.GenerateSink();
-
-  if (!N)
-    return;
-  
-  if (!BT)
-    BT = new BuiltinBug("Return of address to stack-allocated memory");
-  
-  // Generate a report for this bug.
-  llvm::SmallString<100> buf;
-  llvm::raw_svector_ostream os(buf);
-  SourceRange range;
-  
-  // Get the base region, stripping away fields and elements.
-  R = R->getBaseRegion();
-  
-  // Check if the region is a compound literal.
-  if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) {    
-    const CompoundLiteralExpr* CL = CR->getLiteralExpr();
-    os << "Address of stack memory associated with a compound literal "
-          "declared on line "
-       << C.getSourceManager().getInstantiationLineNumber(CL->getLocStart())
-       << " returned to caller";    
-    range = CL->getSourceRange();
-  }
-  else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(R)) {
-    const Expr* ARE = AR->getExpr();
-    SourceLocation L = ARE->getLocStart();
-    range = ARE->getSourceRange();    
-    os << "Address of stack memory allocated by call to alloca() on line "
-       << C.getSourceManager().getInstantiationLineNumber(L)
-       << " returned to caller";
-  }
-  else if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
-    const BlockDecl *BD = BR->getCodeRegion()->getDecl();
-    SourceLocation L = BD->getLocStart();
-    range = BD->getSourceRange();
-    os << "Address of stack-allocated block declared on line "
-       << C.getSourceManager().getInstantiationLineNumber(L)
-       << " returned to caller";
-  }
-  else if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
-    os << "Address of stack memory associated with local variable '"
-       << VR->getString() << "' returned";
-    range = VR->getDecl()->getSourceRange();
-  }
-  else {
-    assert(false && "Invalid region in ReturnStackAddressChecker.");
+  if (R->hasStackStorage()) {
+    EmitStackError(C, R, RetE);
     return;
   }
-
-  RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
-  report->addRange(RetE->getSourceRange());
-  if (range.isValid())
-    report->addRange(range);
-  
-  C.EmitReport(report);
 }