On Fri, 17 Apr 2015, Steve Ellcey wrote:

> On Sat, 2015-04-18 at 00:15 +0200, Marc Glisse wrote:
> > >
> > > extern void bad (const char *__assertion)  __attribute__ ((__noreturn__));
> > > struct link_map { long int l_ns; };
> > > extern struct link_namespaces
> > >  {
> > >    unsigned int _ns_nloaded;
> > >  } _dl_ns[1];
> > > void _dl_close_worker (struct link_map *map)
> > > {
> > >  long int nsid = map->l_ns;
> > >  struct link_namespaces *ns = &_dl_ns[nsid];
> > >  (nsid != 0) ? (void) (0) : bad ("nsid != 0");
> > >  --ns->_ns_nloaded;
> > > }
> > 
> > It looks close enough to me. The actual access to _dl_ns[nsid] only ever 
> > happens for an index that is out of range. The last line of the function 
> > can never make sense (unreachable or undefined behavior), it is good that 
> > the compiler tells you about it.
> 
> I guess, but it left me very confused because the compiler didn't point
> me at the last line, it pointed me at the '*ns = &_dl_ns[nsid]' line.
> If there was a lot of stuff in between that line, the line with the call
> to the noreturn function, and the ns->ns_loaded line (like there is in
> the real glibc), it is very hard to understand what the compiler is
> trying to tell me when it only points out the first line as where the
> error is.

Yeah - we actually warn on both

 _4 = MEM[(struct link_namespaces *)&_dl_ns][nsid_8]._ns_nloaded;

and

 MEM[(struct link_namespaces *)&_dl_ns][nsid_8]._ns_nloaded = _5;

which is also why you get two warnings.  The location of the
ARRAY_REF is that of the original address taking operation.
What eventually misses is the location of the dereference
statement (line 12).

Richard.

Reply via email to