On Mon, 11 May 2015, Marek Polacek wrote: > The problem here isn't in the -Wshift-negative-value warning itself; the > problem is with marking -1 << 0 as a non-constant: later on, we warn in > a context where a constant expression is needed ("initializer element is > not a constant expression"), and for e.g. int foo = -1 << 0 | 9; there's > an error ("initializer element is not constant").
For cases that are not integer constant expressions but can be folded to constants (e.g. where the unevaluated half of ?: contains a function call, which is not allowed in constant expressions), the general approach is a pedwarn-if-pedantic, e.g.: if (TREE_CODE (value) != INTEGER_CST) { value = c_fully_fold (value, false, NULL); if (TREE_CODE (value) == INTEGER_CST) pedwarn (loc, OPT_Wpedantic, "enumerator value for %qE is not an integer " "constant expression", name); } if (TREE_CODE (value) != INTEGER_CST) { error ("enumerator value for %qE is not an integer constant", name); value = 0; } (and similar for various cases other than enums - it turns out the Linux kernel has or had lots of cases that aren't strictly integer constant expressions but are used in contexts requiring such). So I think the issue here is that the above expression isn't folded to a constant by c_fully_fold. If the expression involves division by zero, say, clearly it's appropriate not to fold; no meaningful result value can be assigned. But for the above expression, a meaningful result can be assigned, so it would seem to make sense to fold. That is, it would make sense for c_fully_fold_internal to fold inside a C_MAYBE_CONST_EXPR with C_MAYBE_CONST_EXPR_INT_OPERANDS set, in the cases where meaningful results can be assigned. The rationale for not folding the contents of a C_MAYBE_CONST_EXPR in c_fully_fold is that folding already took place when the C_MAYBE_CONST_EXPR was created, and it's inefficient to potentially fold the same expression recursively many times. But that's only the case for "normal" C_MAYBE_CONST_EXPRs, not those with C_MAYBE_CONST_EXPR_INT_OPERANDS set that indicate something that could occur an unevaluated part of an integer constant expression. And in any case, if folding had already occurred, there would already be the potential for duplicate folding through the existing uses of remove_c_maybe_const_expr. Thus I think this issue should be addressed through folding in c_fully_fold_internal in this case, while watching carefully to make sure it doesn't reduce any other cases (division by zero, negative or out of range shift, overflows) to pedwarns-if-pedantic if they aren't already. There would then remain the matter of "initializer element is not a constant expression" being an unconditional pedwarn_init rather than a pedwarn-if-pedantic, so I think you'd still get warnings that couldn't be disabled for the above code (which would turn into errors with -Werror). The answer for that is probably to make this pedwarn_init use OPT_Wpedantic, consistent with the various other cases that handle things that aren't constant expressions but folded to constants. -- Joseph S. Myers jos...@codesourcery.com