aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-09-21 10:08:29 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:03:15 -0700
commit8be526d647aae30353c172add2563ec64bdf0248 (patch)
treea72c78ad51ffbecff0ab75a2127411cd9bbf9b68
parent4342dcd4f26a3f0ac9e2304303829d13b399c69b (diff)
downloadsparse-dev-8be526d647aae30353c172add2563ec64bdf0248.tar.gz
Improve sign warnings a bit.
We always warn about clashing _explicit_ signs. We don't warn about non-explicitly signed "char". The non-explicitly signed other types are still under consideration, but for now we warn about them with a different warning message.
-rw-r--r--evaluate.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/evaluate.c b/evaluate.c
index a8659a64..65e5d5a2 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -440,8 +440,8 @@ static struct symbol *evaluate_add(struct expression *expr)
#define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG)
#define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE | \
- MOD_ASSIGNED | MOD_USERTYPE | MOD_FORCE | MOD_ACCESSED)
-#define MOD_SIGNEDNESS (MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED)
+ MOD_ASSIGNED | MOD_USERTYPE | MOD_FORCE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
+#define MOD_SIGNEDNESS (MOD_SIGNED | MOD_UNSIGNED)
const char * type_difference(struct symbol *target, struct symbol *source,
unsigned long target_mod_ignore, unsigned long source_mod_ignore)
@@ -533,19 +533,22 @@ const char * type_difference(struct symbol *target, struct symbol *source,
if (as1 != as2)
return "different address spaces";
- /* Ignore differences in storage types, sign, or addressability */
+ /* Ignore differences in storage types or addressability */
diff = (mod1 ^ mod2) & ~MOD_IGNORE;
+ diff &= (mod1 & ~target_mod_ignore) | (mod2 & ~source_mod_ignore);
if (diff) {
- mod1 &= diff & ~target_mod_ignore;
- mod2 &= diff & ~source_mod_ignore;
- mod1 |= mod2;
- if (mod1) {
- if (mod1 & MOD_SIZE)
- return "different type sizes";
- if (!(mod1 & ~MOD_SIGNEDNESS))
- return "different signedness";
+ if (diff & MOD_SIZE)
+ return "different type sizes";
+ if (diff & ~MOD_SIGNEDNESS)
return "different modifiers";
- }
+
+ /* Differs in signedness only.. Sometimes ok - but not if both are explicit */
+ if ((mod1 | mod2) & MOD_EXPLICITLY_SIGNED)
+ return "different explicit signedness";
+
+ /* "char" matches both "unsigned char" and "signed char" */
+ if (!(mod1 & MOD_CHAR))
+ return "different signedness";
}
if (type1 == SYM_FN) {