xazax.hun added a comment.

In http://reviews.llvm.org/D15007#298086, @dcoughlin wrote:

> Gabor, thanks for taking a look at this!
>
> I'm not sure `RegionStore::getBinding()` is the right place to put this logic.
>
> First, not all dereferences of a `std::nullptr_t` value go through 
> `getBinding()`, so, for example, the following snippet triggers the assertion 
> even with your patch:
>
>   decltype(nullptr) returnsNullPtrType();
>   void fromReturnType() {
>     ((X *)returnsNullPtrType())->f(); // Crash in analysis!
>   }
>


Thank you for spotting this, I will definitely try the approach you suggested.

> Second, not all locations of type `std::nullptr_t` contain `0`. For example, 
> the following prints "1" on my machine:

> 

>   #include <iostream>

>   

>   int main() {

>     decltype(nullptr) x;

>     std::cout << (bool)x << "\n";

>   }

> 

> 

> That is, a default-initialized (garbage) nullptr_t may not be '0'. Prior to 
> your patch the analyzer would warn here about `x` being uninitialized (when 
> the analyzer is compiled without asserts) -- but with your patch we lose that 
> warning.


I am not entirely sure what the correct behavior is here. According to the 
standard (2.14.7): "std::nullptr_t is a distinct type that is neither a pointer 
type nor a pointer to member type; rather, a prvalue of this type is a null 
pointer constant and can be converted to a null pointer value or null member 
pointer value." My interpretation is that, the std::nullptr_t does not have a 
state, it just converts to a null pointer value regardless what value is at the 
location of the nullptr_t. Regardless what the standard says it looks like the 
value of std::nullptr_t can be (ab)used in the current clang implementation.

> What do you think about moving your new logic to the symbol value creation 
> methods in SValBuilder? More specifically, you could add the check for 
> nullptr_t to `getRegionValueSymbolVal()`, `conjureSymbolVal()` (both 
> variants), `getConjuredHeapSymbolVal()`, and 
> `getDerivedRegionValueSymbolVal()`. This would let the analyzer warn when it 
> knows there is a garbage value in a location of type nullptr_t but still 
> optimistically assume that the value is is '0' when the value would otherwise 
> be symbolic.

> 

> With this approach we would retain uninitialization warnings about accesses 
> via definitely uninitialized storage:

> 

>   void fromUninitializedLocal() {

>     decltype(nullptr) p;

>     ((X *)p)->f(); // Warn about p being uninitialized

>   }

>   

>   void fromUninitializedLocalStruct() {

>     Type t;

>     ((X *)t.x)->f(); // Warn about t.x being uninitialized.

>   }

> 

> 

> but would warn about about a null access in `returnsNullPtrType()` and would 
> keep the behavior you specify in your `f()` test because `p` is a parameter 
> (and thus its value is symbolic).


I will look into this thank you.


http://reviews.llvm.org/D15007



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to