[cfe-dev] provide a hint to clang-analyzer-optin.portability.UnixAPI?

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Sun Mar 15 21:35:38 PDT 2020


It looks like we don't understand that size_in_bytes() always returns 
the same value. There may be multiple reasons for this. I'd like to see 
the whole code in order to understand what's going on. Could you produce 
a preprocessed file and attach it together with the analyzer invocation?

As a workaround / suppression you should be able to do something like this:

   static void *make_data_ptr(RHS rhs) {
     if (!rhs.has_data())
       return nullptr;

     size_t size = rhs.size_in_bytes();
     return size ? malloc(size) : nullptr;
   }

   Ctor(RHS rhs): data_ptr(make_data_ptr(rhs)) {}

This would prevent the analyzer (and, well, your actual generated code) 
from calling size_in_bytes() twice and believing that it may return two 
different values.

On 2/28/20 5:41 PM, Robert Underwood via cfe-dev wrote:
>
> To whom it may concern,
>
> tl;dr I think I found a bug in the clang static analyzer. Could 
> someone please help me find a workaround/where to properly report the bug?
>
> I have a statement in a class initializer list:
>
> |data_ptr((rhs.has_data() && rhs.size_in_bytes() > 0)? 
> malloc(rhs.size_in_bytes()) : nullptr)|
>
> rhs.has_data() is a const function that returns t/f if rhs.data_ptr != 
> null
>
> rhs.size_in_bytes() a const function that returns the number of bytes 
> in the structure *if has_data was true*
>
> i.e. it is possible that rhs.has_data() is false, and 
> rhs.size_in_bytes() > 0
>
> However the clang static analyzer seems to get a false positive here.
>
> |/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include/g++-v8/bits/unique_ptr.h:831:34: 
> note: Calling copy constructor for 'pressio_data' 
> ../include/libpressio_ext/cpp/data.h:247:15: note: Left side of '&&' 
> is true data_ptr((rhs.has_data() && rhs.size_in_bytes() > 0)? 
> malloc(rhs.size_in_bytes()) : nullptr), ^ 
> ../include/libpressio_ext/cpp/data.h:247:33: note: Assuming the 
> condition is true data_ptr((rhs.has_data() && rhs.size_in_bytes() > 
> 0)? malloc(rhs.size_in_bytes()) : nullptr), ^ 
> ../include/libpressio_ext/cpp/data.h:247:14: note: '?' condition is 
> true data_ptr((rhs.has_data() && rhs.size_in_bytes() > 0)? 
> malloc(rhs.size_in_bytes()) : nullptr), ^ 
> ../include/libpressio_ext/cpp/data.h:247:66: note: Calling 
> 'pressio_data::size_in_bytes' data_ptr((rhs.has_data() && 
> rhs.size_in_bytes() > 0)? malloc(rhs.size_in_bytes()) : nullptr), ^ 
> ../include/libpressio_ext/cpp/data.h:384:12: note: Calling 
> 'data_size_in_bytes<unsigned long>' return 
> data_size_in_bytes(data_dtype, num_dimensions(), dims.data()); ^ 
> ../include/libpressio_ext/cpp/data.h:31:5: note: Returning zero return 
> data_size_in_elements(dimensions, dims) * pressio_dtype_size(type); ^ 
> ../include/libpressio_ext/cpp/data.h:384:12: note: Returning from 
> 'data_size_in_bytes<unsigned long>' return 
> data_size_in_bytes(data_dtype, num_dimensions(), dims.data()); ^ 
> ../include/libpressio_ext/cpp/data.h:384:5: note: Returning zero 
> return data_size_in_bytes(data_dtype, num_dimensions(), dims.data()); 
> ^ ../include/libpressio_ext/cpp/data.h:247:66: note: Returning from 
> 'pressio_data::size_in_bytes' data_ptr((rhs.has_data() && 
> rhs.size_in_bytes() > 0)? malloc(rhs.size_in_bytes()) : nullptr), ^ 
> ../include/libpressio_ext/cpp/data.h:247:59: note: Call to 'malloc' 
> has an allocation size of 0 bytes data_ptr((rhs.has_data() && 
> rhs.size_in_bytes() > 0)? malloc(rhs.size_in_bytes()) : nullptr), |
>
> Is there a way to instruct the static analyzer that malloc cannot be 
> called with size_in_bytes == 0 because saying (rhs.size_in_bytes() > 
> 0) isn’t enough. I’m using clang-9.0.1 on gentoo.
>
> Respectfully,
> Robert Underwood
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list