On Mon, Feb 11, 2013 at 11:48 AM, Jeff Law <[email protected]> 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