On Mon, Feb 11, 2013 at 11:48 AM, Jeff Law <suzanne.jeff....@gmail.com> wrote:
>
> Consider this code in va_gc::reserve:
>
>
> template<typename T, typename A>
> void
> va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact
>                 MEM_STAT_DECL)
> {
>   unsigned alloc
>     = vec_prefix::calculate_allocation (v ? &v->vecpfx_ : 0, reserve,
> exact);
>   if (!alloc)
>     {
>       ::ggc_free (v);
>       v = NULL;
>       return;
>     }
> [ ... ]
>
>
> Note how it assigns NULL to v.

But only when calculate_allocation returns 0.  If reserve > 0, then
calculate_allocation can never return 0.

> Now consider how this gets used in other vec code:
>
> /* If V has no room for one more element, reallocate it.  Then call
>    V->quick_push(OBJ).  */
> template<typename T, typename A>
> inline T *
> vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)
> {
>   vec_safe_reserve (v, 1, false PASS_MEM_STAT);
>   return v->quick_push (obj);
> }
>
>
> /* if V has no room for one more element, reallocate it.  Then call
>    V->quick_insert(IX, OBJ).  */
> template<typename T, typename A>
> inline void
> vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj
>                  CXX_MEM_STAT_INFO)
> {
>   vec_safe_reserve (v, 1, false PASS_MEM_STAT);
>   v->quick_insert (ix, obj);
> }
>
>
> So vec_prefix::calculate_allocation returns NULL, then
> vec_safe_{push,insert} (and possibly others) can dereference a NULL pointer
> if I'm reading the code correctly.

But those cases are passing 1 to vec_safe_reserve, which in turn
passes 1 to calculate_allocation, so calculate_allocation can not
return 0, so vec_reserve can not return NULL.

At least that is how it seems to me.

Ian

Reply via email to