I think we need to go back and revisit this hunk: > /* If the offset is known to be out of bounds, warn, and call strlen at > runtime. */ > if (eltoff < 0 || eltoff >= maxelts) > { > /* Suppress multiple warnings for propagated constant strings. */ > if (only_value != 2 > && !TREE_NO_WARNING (arg) > && warning_at (loc, OPT_Warray_bounds, > "offset %qwi outside bounds of constant string", > eltoff)) > { > if (decl) > inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl); > TREE_NO_WARNING (arg) = 1; > } > return NULL_TREE; > }
The problem we have is this is warning inside a utility routine that can be called many times. ARG is often going to be an ADDR_EXPR that wraps a _DECL node. So we'll end up setting TREE_NO_WARNING on the ADDR_EXPR node. At first glance that seems fine, but it's really not sufficient to avoid duplicate warnings. Consider that we might call get_range_strlen for ARG again later in the optimizer pipeline. That will call the overloaded get_range_strlen which has the VISITED/RKIND arguments via: > bool > get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize) > { > bitmap visited = NULL; > > if (!get_range_strlen (arg, &visited, SRK_LENRANGE, pdata, eltsize)) That overload will call get_range_strlen_tree via: > static bool > get_range_strlen (tree arg, bitmap *visited, > strlen_range_kind rkind, > c_strlen_data *pdata, unsigned eltsize) > { > > if (TREE_CODE (arg) != SSA_NAME) > return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize); get_range_strlen_tree in turn calls c_strlen which may return NULL which results in stripping the ADDR_EXPR and calling get_range_strlen again via: > else > { > c_strlen_data lendata = { }; > val = c_strlen (arg, 1, &lendata, eltsize); > > if (!val && lendata.decl) > { > /* ARG refers to an unterminated const character array. > DATA.DECL with size DATA.LEN. */ > val = lendata.minlen; > pdata->decl = lendata.decl; > } > } > > if (!val && rkind == SRK_LENRANGE) > { > if (TREE_CODE (arg) == ADDR_EXPR) > return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind, > pdata, eltsize); Note that we've stripped the ADDR_EXPR before the call to get_range_strlen here. So we have no way to know we've already warned on this expression and boom it's trivial to get multiple warnings simply by asking for the range of a node. This is a great example of why warning from folders and other routines that may be called more than once (directly or indirectly) is a bad idea. I think you need to find another place for this warning, preferably outside the folders and their utility routines. jeff