[cfe-commits] r86129 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaOverload.cpp test/SemaTemplate/instantiate-complete.cpp utils/C++Tests/LLVM-Syntax/lit.local.cfg

Chris Lattner clattner at apple.com
Thu Nov 5 22:59:54 PST 2009


On Nov 5, 2009, at 8:54 PM, Douglas Gregor wrote:

>>
>> We build with GCC with this warning though, it clang producing it  
>> in cases where GCC isn't?
>
> Yes. All of the cases where Clang is producing a warning (but GCC  
> doesn't) seem to have a cast on at least one side of the == or !=.

Here are some comments from the GCC implementation.  It only emits  
this for code that is not "skip_evaluation" whatever that is (not in a  
template?).

For ?:, the algorithm is:

       /* If -Wsign-compare, warn here if type1 and type2 have
	 different signedness.  We'll promote the signed to unsigned
	 and later code won't know it used to be different.
	 Do this check on the original types, so that explicit casts
	 will be considered, but default promotions won't.  */

...
	      /* Do not warn if the result type is signed, since the
		 signed type will only be chosen if it can represent
		 all the values of the unsigned type.  */
...
	      /* Do not warn if the signed quantity is an unsuffixed
		 integer literal (or some static constant expression
		 involving such literals) and it is non-negative.  */

This last part (known non-negative) involves a bunch of adhoc stuff  
using fold to determine whether something is non-negative, allowing it  
to catch things like 'abs' idioms etc.  We don't need to be this smart  
imo :), but it would be nice to catch integer literals.


For sign/unsigned comparisons, I see these comments:


	      /* Give warnings for comparisons between signed and unsigned
		 quantities that may fail.

		 Do the checking based on the original operand trees, so that
		 casts will be considered, but default promotions won't be.

		 Do not warn if the comparison is being done in a signed type,
		 since the signed type will only be chosen if it can represent
		 all the values of the unsigned type.  */
...
	      /* Do not warn if both operands are the same signedness.  */
...

		  /* Do not warn if the signed quantity is an
		     unsuffixed integer literal (or some static
		     constant expression involving such literals or a
		     conditional expression involving such literals)
		     and it is non-negative.  */
...
		  /* Do not warn if the comparison is an equality operation,
		     the unsigned quantity is an integral constant, and it
		     would fit in the result if the result were signed.  */
...
		  /* Do not warn if the unsigned quantity is an enumeration
		     constant and its maximum value would fit in the result
		     if the result were signed.  */



Nearby they also have an interesting warning that I've never seen  
generated:


	      /* Warn if two unsigned values are being compared in a size
		 larger than their original size, and one (and only one) is the
		 result of a `~' operator.  This comparison will always fail.

		 Also warn if one operand is a constant, and the constant
		 does not have all bits set that are set in the ~ operand
		 when it is extended.  */

which results in:
			    warning (0, "comparison of promoted ~unsigned with constant");


-Chris



More information about the cfe-commits mailing list