bool shouldProceed(void *S, void *T) { using namespace clang; Sema *Sem = (Sema *)S; DiagnosticsEngine& Diag = Sem->getDiagnostics(); cling::Transaction* Trans = (cling::Transaction*)T; // Here we will cheat a bit and assume that the warning came from the last // stmt, which will be in the 90% of the cases. CompoundStmt* CS = cast<CompoundStmt>(Trans->getWrapperFD()->getBody()); // Skip the NullStmts. SourceLocation Loc = CS->getLocStart(); for(CompoundStmt::const_reverse_body_iterator I = CS->body_rbegin(), E = CS->body_rend(); I != E; ++I) if (!isa<NullStmt>(*I)) { Loc = (*I)->getLocStart(); break; } Diag.Report(Loc, diag::warn_null_ptr_deref); if (isatty(fileno(stdin))) { int input = getchar(); getchar(); if (input == 'y' || input == 'Y') return false; } return true; }
/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a /// function that should return a value. Check that we don't fall off the end /// of a noreturn function. We assume that functions and blocks not marked /// noreturn will return. static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, QualType BlockTy, const CheckFallThroughDiagnostics& CD, AnalysisContext &AC) { bool ReturnsVoid = false; bool HasNoReturn = false; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { ReturnsVoid = FD->getResultType()->isVoidType(); HasNoReturn = FD->hasAttr<NoReturnAttr>() || FD->getType()->getAs<FunctionType>()->getNoReturnAttr(); } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { ReturnsVoid = MD->getResultType()->isVoidType(); HasNoReturn = MD->hasAttr<NoReturnAttr>(); } else if (isa<BlockDecl>(D)) { if (const FunctionType *FT = BlockTy->getPointeeType()->getAs<FunctionType>()) { if (FT->getResultType()->isVoidType()) ReturnsVoid = true; if (FT->getNoReturnAttr()) HasNoReturn = true; } } Diagnostic &Diags = S.getDiagnostics(); // Short circuit for compilation speed. if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn)) return; // FIXME: Function try block if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { switch (CheckFallThrough(AC)) { case UnknownFallThrough: break; case MaybeFallThrough: if (HasNoReturn) S.Diag(Compound->getRBracLoc(), CD.diag_MaybeFallThrough_HasNoReturn); else if (!ReturnsVoid) S.Diag(Compound->getRBracLoc(), CD.diag_MaybeFallThrough_ReturnsNonVoid); break; case AlwaysFallThrough: if (HasNoReturn) S.Diag(Compound->getRBracLoc(), CD.diag_AlwaysFallThrough_HasNoReturn); else if (!ReturnsVoid) S.Diag(Compound->getRBracLoc(), CD.diag_AlwaysFallThrough_ReturnsNonVoid); break; case NeverFallThroughOrReturn: if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); break; case NeverFallThrough: break; } } }