Warn if flags is signed instead of unsigned (bug #3279)
authorMark Spencer <markster@digium.com>
Sat, 8 Jan 2005 19:00:46 +0000 (19:00 +0000)
committerMark Spencer <markster@digium.com>
Sat, 8 Jan 2005 19:00:46 +0000 (19:00 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4713 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_queue.c
apps/app_voicemail.c
include/asterisk/channel.h
include/asterisk/utils.h

index b78f947..ef7115d 100755 (executable)
@@ -183,7 +183,7 @@ struct localuser {
        int stillgoing;
        int metric;
        int oldstatus;
-       int flags;                      /* flag bits */
+       unsigned int flags;             /* flag bits */
        time_t lastcall;
        struct member *member;
        struct localuser *next;
@@ -224,7 +224,7 @@ struct ast_call_queue {
        char moh[80];                   /* Name of musiconhold to be used */
        char announce[80];              /* Announcement to play when call is answered */
        char context[80];               /* Context for this queue */
-       int flags;                      /* flag bits */
+       unsigned int flags;             /* flag bits */
        int strategy;                   /* Queueing strategy */
        int announcefrequency;          /* How often to announce their position */
        int roundingseconds;            /* How many seconds do we round to? */
index b4d4c9d..d33259f 100755 (executable)
@@ -157,7 +157,7 @@ struct ast_vm_user {
        char dialout[80];
        char uniqueid[20];              /* Unique integer identifier */
        char exit[80];
-       int flags;                      /* VM_ flags */ 
+       unsigned int flags;             /* VM_ flags */ 
        int saydurationm;
        struct ast_vm_user *next;
 };
index 765e7ff..2bd38b2 100755 (executable)
@@ -218,7 +218,7 @@ struct ast_channel {
        unsigned int pickupgroup;
 
        /*! channel flags of AST_FLAG_ type */
-       int flags;
+       unsigned int flags;
        
        /*! For easy linking */
        struct ast_channel *next;
@@ -251,7 +251,7 @@ struct ast_bridge_config {
        char *end_sound;
        char *start_sound;
        int firstpass;
-       int flags;
+       unsigned int flags;
 };
 
 struct chanmon;
index 9798543..ff42c13 100755 (executable)
 #include <asterisk/lock.h>
 #include <limits.h>
 
-#define ast_test_flag(p,flag)          ((p)->flags & (flag))
-
-#define ast_set_flag(p,flag)           ((p)->flags |= (flag))
-
-#define ast_clear_flag(p,flag)         ((p)->flags &= ~(flag))
-
-#define ast_copy_flags(dest,src,flagz) do { (dest)->flags &= ~(flagz); \
-                                       (dest)->flags |= ((src)->flags & (flagz)); } while(0)
-
-#define ast_set2_flag(p,value,flag)    ((value) ? ast_set_flag(p,flag) : ast_clear_flag(p,flag))       
+/* Note:
+   It is very important to use only unsigned variables to hold
+   bit flags, as otherwise you can fall prey to the compiler's
+   sign-extension antics if you try to use the top two bits in
+   your variable.
+
+   The flag macros below use a set of compiler tricks to verify
+   that the caller is using an "unsigned int" variable to hold
+   the flags, and nothing else. If the caller uses any other
+   type of variable, a warning message similar to this:
+
+   warning: comparison of distinct pointer types lacks cast
+
+   will be generated.
+
+   The "dummy" variable below is used to make these comparisons.
+
+   Also note that at -O2 or above, this type-safety checking
+   does _not_ produce any additional object code at all.
+*/
+
+extern unsigned int __unsigned_int_flags_dummy;
+
+#define ast_test_flag(p,flag)          ({ \
+                                       typeof ((p)->flags) __p = (p)->flags; \
+                                       typeof (__unsigned_int_flags_dummy) __x = 0; \
+                                       (void) (&__p == &__x); \
+                                       ((p)->flags & (flag)); \
+                                       })
+
+#define ast_set_flag(p,flag)           do { \
+                                       typeof ((p)->flags) __p = (p)->flags; \
+                                       typeof (__unsigned_int_flags_dummy) __x = 0; \
+                                       (void) (&__p == &__x); \
+                                       ((p)->flags |= (flag)); \
+                                       } while(0)
+
+#define ast_clear_flag(p,flag)                 do { \
+                                       typeof ((p)->flags) __p = (p)->flags; \
+                                       typeof (__unsigned_int_flags_dummy) __x = 0; \
+                                       (void) (&__p == &__x); \
+                                       ((p)->flags &= ~(flag)); \
+                                       } while(0)
+
+#define ast_copy_flags(dest,src,flagz) do { \
+                                       typeof ((dest)->flags) __d = (dest)->flags; \
+                                       typeof ((src)->flags) __s = (src)->flags; \
+                                       typeof (__unsigned_int_flags_dummy) __x = 0; \
+                                       (void) (&__d == &__x); \
+                                       (void) (&__s == &__x); \
+                                       (dest)->flags &= ~(flagz); \
+                                       (dest)->flags |= ((src)->flags & (flagz)); \
+                                       } while (0)
+
+#define ast_set2_flag(p,value,flag)    do { \
+                                       typeof ((p)->flags) __p = (p)->flags; \
+                                       typeof (__unsigned_int_flags_dummy) __x = 0; \
+                                       (void) (&__p == &__x); \
+                                       if (value) \
+                                               (p)->flags |= (flag); \
+                                       else \
+                                               (p)->flags &= ~(flag); \
+                                       } while (0)
 
 #define AST_FLAGS_ALL UINT_MAX
 
+struct ast_flags {
+       unsigned int flags;
+};
+
 static inline int ast_strlen_zero(const char *s)
 {
        return (*s == '\0');
@@ -41,10 +98,6 @@ struct ast_hostent {
        char buf[1024];
 };
 
-struct ast_flags {
-       unsigned int flags;
-};
-
 extern char *ast_strip(char *buf);
 extern struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
 extern int ast_base64encode(char *dst, unsigned char *src, int srclen, int max);