The language leaves it up to compilers to choose how to implement implementation-defined and undefined behavior. LLVM historically didn't provide a way to get safe implementations of most undefined behaviors but -fsanitize=undefined -fsanitize-trap=undefined is exactly that.
Conversation
How is that not a dialect? This code will work on compilers that implement zero-init and will likely fail randomly or have vulnerabilities on compilers that don't.
Perhaps we don't have a common understanding of what a dialect is.
1
1
1
They say that zero init is a dialect but initialization with any other byte pattern chosen by the developer is somehow not a dialect. That doesn't make any sense. Regardless of how a dialect is defined, either both of those are language dialects or neither of them is a dialect.
1
Similarly, if zero-init is a dialect, so is trapping or zero-or-trap. These are all ways of defining an undefined behavior which the language leaves up to compilers to handle. The -ftrivial-auto-var-init=zero switch does NOT make it correct to use uninitialized data. Still a bug.
2
The -ftrivial-auto-var-init=zero switch does not disable warnings for uninitialized variable usage and does not stop sanitizers like MSan from catching it. It's still a bug. It doesn't permit doing something but rather makes it less unsafe like CFI, ASLR, stack canaries, [...].
1
2
In this case, if it is still reported as a bug by those tools, it definitely smells less like a dialect.
1
1
Permitting uninitialized variable usage by defining variables to be zero initialized would be a separate discussion to have and isn't what this switch is doing. This is just a code generation change. Sure, people can disable the warnings and rely on it but not the only example.
1
It's not like-fwrapv, which disables signed integer overflow warnings and disables the signed-integer-overflow sanitizer. That's explicitly a language dialect, as are the thousands of extensions that Clang makes to the language. This option is more like -fstack-protector.
1
I disagree a bit, because all the flags that terminate the program when something goes wrong are materially different from ones that turn UB into a consistent, useful behavior.
APIs and other abstractions are littered with cases where people came to depend on those behaviors...
1
... but no one is depending on stack protector for a correct program: it's just a layer of defence against incorrect ones.
1
In some implementations it adds a guaranteed NUL byte to the end of the stack frame and some programs crash if it's disabled since they've accidentally relied upon it to terminate their strings outside of defined behavior.
Similarly, programs accidentally rely upon the stack being initially zeroed, since in practice it is for the initial usage, including for secondary stacks. Implementations caring more about security won't reuse stacks so programs could accidentally rely more on stacks being zero.
1
That's one of the reasons that programs already rely on zero-on-init semantics. The initial call chain down the stack will have zeroed frames in practice. It only starts being non-zero once there are returns and it's reusing stack space that was already used previously.
1
Show replies

