Il 12/06/21 15:05, Ville Voutilainen via Std-Proposals ha scritto:
template <class T> remove_cvref_t<T> unsanitize(T&& t);
Returns: Either t or an unspecified value. If an unspecified value is
returned, the value and copies of the
value may be treated as indeterminate values until a subsequent
assignment or bitwise copy of a non-indeterminate
value is performed to the storage location where such a result or copy
of the result of unsanitize() is stored.
Basically the problem™ today would be that an implementation such as
#if defined(__has_feature) && __has_feature(memory_sanitizer)
T x;
return x;
#else
return std::forward<T>(t);
#endif
would make MSAN trip on the return itself? (Didn't try on a complete testcase...)
Yeah, I haven't been able to think of a way to return a poisoned/tainted value that wouldn't already trip up an analyzer.
Perhaps this warrants a distinct class of values. It doesn't fit in with the lvalue, xvalue, prvalue categories, but rather another kind of value property. I think there is a distinction to be made between a poisoned value vs some other tainted or not-yet-sanitized value; any access of the former indicates a defect while for the latter, the value may be sanitized through validation (as is common when data is read from the network, a file, user input, etc...).
In either case, I think there is a need to be able to propagate poison/taint. From the earlier example:
struct S {
S() {}
S(int v) : dm(v) {}
// dm may only be used if a value was provided during construction.
int dm = POISON(-1);
};
Copy construction of an S object (whether by a default copy
constructor or user provided copy constructor, assuming the latter
actually does a copy) should propagate poison/taint, not be itself
indicative of a defect. Drawing this line may be challenging or
may require an opt-out mechanism like MemorySanitizer's
no_sanitize attribute.
Tom.
Thanks,