From f7e7bd4c3b974bb1fde97f57650a203c36dd9bbf Mon Sep 17 00:00:00 2001 From: Chih-Hung Hsieh Date: Wed, 3 Feb 2016 10:40:45 -0800 Subject: [PATCH] Suppress false positive memory leak warnings. Clang static analyzer does not know the transfer of object ownership to hashmapPut. Use a fake global pointer variable to trick the analyzer. BUG: 26955438 Change-Id: Id3ac595fff14e48d28a1147461cd836914857086 --- libcutils/str_parms.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c index 4f23d09c5..8dafdedac 100644 --- a/libcutils/str_parms.c +++ b/libcutils/str_parms.c @@ -31,6 +31,20 @@ #define UNUSED __attribute__((unused)) +/* When an object is allocated but not freed in a function, + * because its ownership is released to other object like a hashmap, + * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid + * false warnings about potential memory leak. + * For now, a "temporary" assignment to global variables + * is enough to confuse the clang static analyzer. + */ +#ifdef __clang_analyzer__ +static void *released_pointer; +#define RELEASE_OWNERSHIP(x) { released_pointer = x; released_pointer = 0; } +#else +#define RELEASE_OWNERSHIP(x) +#endif + struct str_parms { Hashmap *map; }; @@ -170,9 +184,12 @@ struct str_parms *str_parms_create_str(const char *_string) /* if we replaced a value, free it */ old_val = hashmapPut(str_parms->map, key, value); + RELEASE_OWNERSHIP(value); if (old_val) { free(old_val); free(key); + } else { + RELEASE_OWNERSHIP(key); } items++; @@ -222,10 +239,13 @@ int str_parms_add_str(struct str_parms *str_parms, const char *key, goto clean_up; } // For new keys, hashmap takes ownership of tmp_key and tmp_val. + RELEASE_OWNERSHIP(tmp_key); + RELEASE_OWNERSHIP(tmp_val); tmp_key = tmp_val = NULL; } else { // For existing keys, hashmap takes ownership of tmp_val. // (It also gives up ownership of old_val.) + RELEASE_OWNERSHIP(tmp_val); tmp_val = NULL; }