[PATCH] Illegal delete/free not detected by clang static analyzer(MallocChecker)

Jordan Rose jordan_rose at apple.com
Fri Aug 2 09:16:22 PDT 2013


The real warning here isn't "Freeing non-allocated memory", it's "Argument to 'delete' is uninitialized". We already get this check for 'free' because it looks like a function call, but right now the same is not true for 'delete'.

Eventually 'delete' will be modeled in terms of a destructor call and a deallocator, and at that point we'd probably get this warning for free. For now, though, this does seem useful.

Please change the patch to only check 'delete' and 'delete[]', change the message to talk about uninitialized memory (and possibly use SVal::isUndef instead), and add tests for both 'delete' forms (plus a test for 'free' to make sure the call checker is still doing its work).

Thanks for tracking this down!
Jordan


On Aug 2, 2013, at 3:06 , Karthik Bhat <blitz.opensource at gmail.com> wrote:

> Hi,
> In case we have a code like -
> 
> int main() {
>   char* p;
>   delete p;  // Illegal Delete
> }
> 
> Illegal delete for statement "delete p" is not reported. Added a patch to fix the same. Please let me know if the patch is ok.
> 
> Index: test/Analysis/malloc-interprocedural.c
> ===================================================================
> --- test/Analysis/malloc-interprocedural.c	(revision 187647)
> +++ test/Analysis/malloc-interprocedural.c	(working copy)
> @@ -68,10 +68,13 @@
>    my_free1((int*)data); // expected-warning{{Use of memory after it is freed}}
>  }
>  
> +static void my_free2(void *p) {
> +  free(p); // expected-warning{{Freeing a non allocated memory}}
> +}
>  // TODO: We should warn here.
>  void test5() {
>    int *data;
> -  my_free1((int*)data);
> +  my_free2((int*)data);
>  }
>  
>  static char *reshape(char *in) {
> Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
> ===================================================================
> --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp	(revision 187648)
> +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp	(working copy)
> @@ -961,8 +961,19 @@
>                                            bool ReturnsNullOnFailure) const {
>  
>    SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
> -  if (!ArgVal.getAs<DefinedOrUnknownSVal>())
> +  if (!ArgVal.getAs<DefinedOrUnknownSVal>()) {
> +    if (ExplodedNode *N = C.addTransition(C.getState())) {
> +      if (!BT_BadFree)
> +        BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
> +      SmallString<100> buf;
> +      llvm::raw_svector_ostream os(buf);
> +      os << "Freeing a non allocated memory";
> +      BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
> +      R->addRange(ArgExpr->getSourceRange());
> +      C.emitReport(R);
> +    }
>      return 0;
> +  }
>    DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
> 
> 
> Thanks and Regards
> Karthik Bhat
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list