Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -47,6 +47,7 @@ #include "AllocationState.h" #include "InterCheckerAPI.h" #include "clang/AST/Attr.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ParentMap.h" @@ -1037,9 +1038,44 @@ C.addTransition(State); } -void MallocChecker::checkRealloc(const CallEvent &Call, - CheckerContext &C, +static bool isStandardRealloc(const CallEvent &Call) { + const FunctionDecl *FD = dyn_cast(Call.getDecl()); + assert(FD); + ASTContext &AC = FD->getASTContext(); + + if (isa(FD)) + return false; + + return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy && + FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy && + FD->getParamDecl(1)->getType().getDesugaredType(AC) == + AC.getSizeType(); +} + +static bool isGRealloc(const CallEvent &Call) { + const FunctionDecl *FD = dyn_cast(Call.getDecl()); + assert(FD); + ASTContext &AC = FD->getASTContext(); + + if (isa(FD)) + return false; + + return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy && + FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy && + FD->getParamDecl(1)->getType().getDesugaredType(AC) == + AC.UnsignedLongTy; +} + +void MallocChecker::checkRealloc(const CallEvent &Call, CheckerContext &C, bool ShouldFreeOnFail) const { + // HACK: CallDescription currently recognizes non-standard realloc functions + // as standard because it doesn't check the type, or wether its a non-method + // function. This should be solved by making CallDescription smarter. + // Mind that this came from a bug report, and all other functions suffer from + // this. + // https://bugs.llvm.org/show_bug.cgi?id=46253 + if (!isStandardRealloc(Call) && !isGRealloc(Call)) + return; ProgramStateRef State = C.getState(); State = ReallocMemAux(C, Call, ShouldFreeOnFail, State, AF_Malloc); State = ProcessZeroAllocCheck(Call, 1, State); Index: clang/test/Analysis/malloc.cpp =================================================================== --- clang/test/Analysis/malloc.cpp +++ clang/test/Analysis/malloc.cpp @@ -172,3 +172,21 @@ // ZERO_SIZE_PTR is specially handled but only for malloc family delete Ptr; // expected-warning{{Argument to 'delete' is a constant address (16)}} } + +namespace pr46253_class { +class a { + void *realloc(int, bool = false) { realloc(1); } // no-crash +}; +} // namespace pr46253_class + +namespace pr46253_retty{ +void realloc(void *ptr, size_t size) { realloc(ptr, size); } // no-crash +} // namespace pr46253_retty + +namespace pr46253_paramty{ +void *realloc(void **ptr, size_t size) { realloc(ptr, size); } // no-crash +} // namespace pr46253_paramty + +namespace pr46253_paramty2{ +void *realloc(void *ptr, int size) { realloc(ptr, size); } // no-crash +} // namespace pr46253_paramty2