2,652 karma · joined May 6, 2012
I spent a few minutes poking just to see if my gut is right here, and already, here's an example of UB being used in an optimization by the compiler that leaves a fil safety check at on -O0 but drops it at higher optimization levels. I find it difficult to believe that all of the complex interactions of every optimization pass in the presence of even this subset of UB are guaranteed not to violate these memory safety promises.
#include <stdio.h>
#include <stdlib.h>
__attribute__((noinline)) static void poke(int *p, int k)
{
int n = 32 + (k & 15); /* always >= 32: shifting an int by >= 32 is UB */
p[(1 << n) * 20] = 0x41414141; /* on x86 the CPU computes index 40, out of bounds */
}
int main(int argc, char **argv)
{
int *p = calloc(16, sizeof(int));
poke(p, argc);
puts("after poke");
return 0;
}The behavior of the program itself when undefined behavior is invoked is allowed to be _anything_. I've simply demonstrated here that the compiler is using the fact that there is undefined behavior to perform optimizations that would not be allowed without undefined behavior. Those optimizations are allowed to result in the program doing anything at the compiler's whim.
To assert that something specific always happens under UB is counter to the definition of UB. Fil-C carefully defines away UB for some operations, but to make full guarantee of safety, even by their definition and modulo bugs, I believe it necessary to fully remove UB.
#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.It’s worth being clear here that this is not what Fil-C does, it still has UB, and can still explode in many of the same ways as C and all (after all, it’s a clang fork). Fil-C takes one particular class of allocation related bugs and UB off the table, but leaves many of them behind.
To be remarkably secure, these projects would need to not have these kinds of defects, despite the combination of being written in languages have that have a long track record of footguns and lack of initiatives to fix them (proposal-symbol-proto, and PHP's list is too long to even start) and being themselves ecosystems with questionable track records on security in the related areas (Look at $wpdb in 2026, or overall code quality and willingness to modernize, or the entirety of the model of RSC for things that are just going to nearly guarantee you punch all kinds of holes on accident).
The “under license terms…” is a pretty important clause you omitted here.
https://dl.packetstormsecurity.net/mag/pocgtfo/pocorgtfo14.p...
This is a lazy strawman and not what the author of the post argued for.
> It's natural, and I get it (ads are annoying), but this is a forum where I expect people to think a little more deeply about the economics and second order effects of things.
Then maybe contribute to the dialog on that front. The article did so more than your comment setting up a strawman.
But you can see in a number of his public comments statements that Rust is not memory safe by his definition because it has unsafe as an escape hatch. https://x.com/filpizlo/status/2079244258062766177 and https://news.ycombinator.com/item?id=49053608 as some examples.
This is an argument that Fil-C makes, by choosing a very specific definition of memory safety. It’s even stated explicitly in that tweet linked.
They store some prompts and responses, not all, that's what you're missing.