#include <stdio.h>
#include <stdlib.h>
int shift(int x, int n) { return x << n; }
int main(int argc, char **argv) {
printf("%d\n", shift(1, 32)); /* n == width: UB */
return 0;
}
This program exhibits UB in Fil-C, and you can see that the optimizer does different things at -O0 (outputs 1) and -O1/-O2/-O3 (outputs 0). Since this creates poison, which Fil-C doesn't remove, you can use it to construct all kinds of weird things.
static void loop(void) {
int s = shift(1, 32);
int n = 0;
for (int i = 0; i < s + 3; i++)
n++;
printf("[loop] iterations=%d (s+3=%d)\n", n, s + 3);
}
static void sw(void) {
switch (shift(1, 32)) {
case 0: puts("[switch] case 0"); break;
case 1: puts("[switch] case 1"); break;
default: puts("[switch] default"); break;
}
}
int main(int argc, char **argv) {
loop();
sw();
return 0;
}
In Fil-C -O0, this gives 4 iterations of the loop and executes sw(). At any higher optimization level, it turns loop() into an infinite loop and drops sw() from the binary entirely.