diff -Nru a/apps/app_queue.c b/apps/app_queue.c --- a/apps/app_queue.c 2005-01-08 10:59:28 -07:00 +++ b/apps/app_queue.c 2005-01-08 10:59:28 -07:00 @@ -183,7 +183,7 @@ 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 @@ 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? */ diff -Nru a/apps/app_voicemail.c b/apps/app_voicemail.c --- a/apps/app_voicemail.c 2005-01-08 10:59:28 -07:00 +++ b/apps/app_voicemail.c 2005-01-08 10:59:28 -07:00 @@ -157,7 +157,7 @@ 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; }; diff -Nru a/include/asterisk/channel.h b/include/asterisk/channel.h --- a/include/asterisk/channel.h 2005-01-08 10:59:28 -07:00 +++ b/include/asterisk/channel.h 2005-01-08 10:59:28 -07:00 @@ -218,7 +218,7 @@ 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 @@ char *end_sound; char *start_sound; int firstpass; - int flags; + unsigned int flags; }; struct chanmon; diff -Nru a/include/asterisk/utils.h b/include/asterisk/utils.h --- a/include/asterisk/utils.h 2005-01-08 10:59:28 -07:00 +++ b/include/asterisk/utils.h 2005-01-08 10:59:28 -07:00 @@ -18,19 +18,76 @@ #include #include -#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'); @@ -39,10 +96,6 @@ struct ast_hostent { struct hostent hp; char buf[1024]; -}; - -struct ast_flags { - unsigned int flags; }; extern char *ast_strip(char *buf);