4 ms·
No, actually the false positive rate of these flags is practically zero. (I'm not sure if it's 100% zero, but I used those extensively, reported many bugs and e
by hannob 7y ago
No, actually the false positive rate of these flags is practically zero. (I'm not sure if it's 100% zero, but I used those extensively, reported many bugs and every time a developer told me "this is a false positive" they were wrong.)
The reason they aren't enabled by default is that that's not what they're designed for. They have a significant performance impact, you can't enable them all at once, they conflict with other security features and they may introduce security issues.
These are developer features. They aren't there to run your production code, they are there to test during development and bug finding.
- saagarjha 7y agoHere's one that I encountered that I cannot figure out: $ g++ -x c++ -fsanitize=undefined - #include <iostream> int main() { int *a = nullptr; std::cout << std::addressof(*a) << std::endl; } ^D $ ./a.out <stdin>:5:29: runtime error: reference binding to null pointer of type 'int' 0
- lallysingh 7y agoDoesn't addressof() take a reference?
- Karliss 7y agoYou are not allowed to dereference a null pointer no matter how you use it even if you later convert it back to address.
- cpdt 7y agoAnd to elaborate on how the error message relates to this: std::addressof takes a reference which also can’t be null. So when you dereference the pointer you’re actually turning it into a reference (or binding the reference to the pointer, as the error message says).
- edflsafoiewq 7y agoIn C99 however, you are allowed to do &٭a because when the operand of & is the result of the unary ٭ operator > neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue
- SAI_Peregrinus 7y agoFor anyone who wants it, this is in section 6.5.3.2 Address and indirection operators, paragraph 3.
- hvdijk 7y agoYou are allowed to dereference a null pointer, but you are not allowed to access the result or use it as an initialiser for a reference. You can only immediately discard the result, or immediately take the result's address. Using std::addressof(* a) first binds a reference, then uses that reference to take the address, hence the error. You won't get any UBSAN error with &*a.
- MaulingMonkey 7y ago> You are allowed to dereference a null pointer Can you cite me something for that? The very first mention of dereferencing in the C++03 standard - ISO/IEC 14882:2003 1.9 Program exection ¶ 4 (page 5) - would seem to disagree: > Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer). [Note: this International Standard imposes no requirements on the behavior of programs that contain undefined behavior. ] EDIT: As does 8.3.2 References ¶ 4 (page 136): > [...] [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bit-field. ]
- hvdijk 7y agoThe standard doesn't say dereferencing a null pointer is invalid. The fact that it gives it as an example of undefined behaviour is a defect in the standard. In the discussion on core language issue #232, the intent has been explicitly stated: > Notes from the October 2003 meeting: > ... > We agreed that the approach in the standard seems okay: p = 0; *p; is not inherently an error. An lvalue-to-rvalue conversion would give it undefined behavior. http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#232 http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#232 WRT your edit: no, that says dereferencing a null pointer and binding a reference to the result produces undefined behaviour. That agrees with what I was saying. "which" refers to the whole of "to bind it to the "object" obtained by dereferencing a null pointer", not just to "dereferencing a null pointer".
- asveikau 7y agoA pretty common way to do the offset_of thing is to take a null pointers. Eg: &foo->member where foo is null. sizeof on invalid pointer dereferences is also pretty common.
- zamalek 7y ago> every time a developer told me "this is a false positive" they were wrong This sounds like a good UB learning experience. The parent comments sounds like the author is running into UB more than they really want to.
- favorited 7y agoI know TSan has zero false-positives, because it only flags a data race when multiple threads access the same memory without synchronization (and at least one of those accesses is a write). Not sure about the other LLVM sanitizers.