diff --git a/src/domains/access.ml b/src/domains/access.ml index fa6446df16..daf530972d 100644 --- a/src/domains/access.ml +++ b/src/domains/access.ml @@ -362,16 +362,14 @@ struct end -(* Check if two accesses may race and if yes with which confidence *) +(** Check if two accesses may race. *) let may_race A.{kind; acc; _} A.{kind=kind2; acc=acc2; _} = - if kind = Read && kind2 = Read then - false (* two read/read accesses do not race *) - else if not (get_bool "ana.race.free") && (kind = Free || kind2 = Free) then - false - else if not (MCPAccess.A.may_race acc acc2) then - false (* analysis-specific information excludes race *) - else - true + match kind, kind2 with + | Read, Read -> false (* two read/read accesses do not race *) + | Free, Free -> false (* two free/free accesses do not race *) + | Free, _ + | _, Free when not (get_bool "ana.race.free") -> false + | _, _ -> MCPAccess.A.may_race acc acc2 (* analysis-specific information excludes race *) (** Access sets for race detection and warnings. *) module WarnAccs = diff --git a/src/util/options.schema.json b/src/util/options.schema.json index 1b9c7d3fd5..88c386ebc3 100644 --- a/src/util/options.schema.json +++ b/src/util/options.schema.json @@ -998,7 +998,7 @@ "properties": { "free": { "title": "ana.race.free", - "description": "Consider memory free as racing write.", + "description": "Consider memory free as racing with read or write (but not another free).", "type": "boolean", "default": true }, diff --git a/tests/regression/04-mutex/64-free_direct_rc.c b/tests/regression/04-mutex/64-free_direct_rc.c index c082dfabbd..952dabb922 100644 --- a/tests/regression/04-mutex/64-free_direct_rc.c +++ b/tests/regression/04-mutex/64-free_direct_rc.c @@ -8,11 +8,23 @@ void *t_fun(void *arg) { return NULL; } +void *t_fun2(void *arg) { + int *p = (int *) arg; + free(p); // NORACE + return NULL; +} + int main(void) { pthread_t id; - int *p = malloc(sizeof(int)); + int *p; + p = malloc(sizeof(int)); pthread_create(&id, NULL, t_fun, (void *) p); free(p); // RACE! pthread_join (id, NULL); + + p = malloc(sizeof(int)); + pthread_create(&id, NULL, t_fun2, (void *) p); + free(p); // NORACE + pthread_join (id, NULL); return 0; }