cil
cil copied to clipboard
Keep side-effect-less expression statements when wanted
This is an even simpler version of #140.
CIL removes side-effect-less standalone expressions completely, but this makes Goblint unsound as it misses a race. For example in
#include <pthread.h>
#include <stdio.h>
int myglobal;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void *t_fun(void *arg) {
pthread_mutex_lock(&mutex1);
myglobal; // RACE!
pthread_mutex_unlock(&mutex1);
return NULL;
}
int main(void) {
pthread_t id;
pthread_create(&id, NULL, t_fun, NULL);
pthread_mutex_lock(&mutex2);
myglobal=myglobal+1; // RACE!
pthread_mutex_unlock(&mutex2);
pthread_join (id, NULL);
return 0;
}
Obviously any sensible compiler just optimizes away, but I don't think the standard demands such optimization. It just says the expression is evaluated:
The expression in an expression statement is evaluated as a void expression for its side effects.
The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
I think the problem is that the CIL AST has no construct that corresponds to this. It's only Cabs which as A.COMPUTATION.
We discussed how to handle this at GobCon today.
We considered two options:
- Compile such an expression as a call to a special function like __builtin_constant_p
- Introduce a constructor for such expressions ( “pure_eval”) in
stmtkind/instructionin CIL, and add a transfer function.
In the discussion we favored the second option as cleaner.