<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Improve diagnostics for zero-size alloc."
   href="http://llvm.org/bugs/show_bug.cgi?id=20361">20361</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Improve diagnostics for zero-size alloc.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.4
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Static Analyzer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>kremenek@apple.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>splinterofchaos@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In the fallowing use-case, scan-build's diagnostics do not help.

==================

// alloc.h
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>

void *xcalloc(size_t, size_t);
void *xmalloc(size_t);

// alloc.c
#include "alloc.h"

void *xcalloc(size_t count, size_t size)
{
  void *ret = calloc(count, size);

  if (!ret && (!count || !size))
    ret = calloc(1, 1);

  if (!ret) {
    //try_to_free_memory();
    ret = calloc(count, size); // warning here
    if (!ret && (!count || !size))
      ret = calloc(1, 1);
    if (!ret) {
      printf("Error: Out of memory.\n");
    }
  }

  return ret;
}

void *xmalloc(size_t size)
{
  void *ret = malloc(size);

  if (!ret && !size)
    ret = malloc(1);

  if (!ret) {
    //try_to_free_memory();
    ret = malloc(size); // no warning
    if (!ret && !size)
      ret = malloc( 1);
    if (!ret) {
      printf("Error: Out of memory.\n");
    }
  }

  return ret;
}

// main.c
#include "alloc.h"

int main() {
  void* p = xcalloc(0,0); // warning expected
  void* q = xmalloc(0);   // warning expected

  printf("int @ %lu = %i\n", (size_t)p, *(int*)p);
  printf("int @ %lu = %i\n", (size_t)q, *(int*)q);
  free(p);
  free(q);
  return 0;
}

// CMakeLists.txt
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
set(CMAKE_EXE_LINKER_FLAGS "${SMAKE_EXE_LINKER_FLAGS} --coverage")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")

add_library(Alloc alloc.c)
add_executable(Main, main.c) 
target_link_libraries(Main, Alloc)

==================


Run with:
$ cmake -DCMAKE_C_COMPILER=/usr/share/clang/scan-build/ccc-analyzer   
-- Configuring done
-- Generating done
-- Build files have been written to: /home/admin/src/test
$ scan-build make -B 
scan-build: Using '/usr/bin/clang' for static analysis
[ 50%] Building C object CMakeFiles/Alloc.dir/alloc.c.o
/home/admin/src/test/alloc.c:14:11: warning: Call to 'calloc' has an allocation
size of 0 bytes
    ret = calloc(count, size);
          ^~~~~~~~~~~~~~~~~~~
1 warning generated.
Linking C static library libAlloc.a
[ 50%] Built target Alloc
[100%] Building C object CMakeFiles/Main,.dir/main.c.o
Linking C executable Main,
[100%] Built target Main,
scan-build: 1 bugs found.
scan-build: Run 'scan-view /tmp/scan-build-2014-07-18-144446-18799-1' to
examine bug reports.


xcalloc() and xmalloc() try never to return NULL unless there is no space left,
and expect the underlying implementation to do the same, but provide a
fall-back in case it doesn't.

scan-build produces a warning for xcalloc()'s definition in alloc.c, but not
the instance, xcalloc(0,0), in main.c. It neither produces a warning for
xmalloc(0), nor xmalloc()'s definition in alloc.c.

xcalloc() may invoke non-uniform behaviour across implementations, but the real
bugs in main.c. In order to help track down zero-sized allocation bugs, or even
implementation-dependent behaviour in legacy code bases, functions like
xcalloc() must be recognized as having the same, or similar, properties as
their underlying *alloc().</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>