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.