sanisizer
Sanitize sizes to avoid integer overflow
Loading...
Searching...
No Matches
ptrdiff.hpp
Go to the documentation of this file.
1#ifndef SANISIZER_PTRDIFF_HPP
2#define SANISIZER_PTRDIFF_HPP
3
4#include <utility>
5
6#include "attest.hpp"
7#include "utils.hpp"
8
14namespace sanisizer {
15
19template<typename Iterator_, typename MaxDiff_>
20constexpr bool can_ptrdiff(MaxDiff_ max_diff) {
21 typedef I<decltype(std::declval<Iterator_>() - std::declval<Iterator_>())> Diff;
22 check_overflow<Diff>(max_diff);
23 return true;
24}
29// It is tempting to write a ptrdiff() function that checks each subtraction for overflow given 'start' and 'end' iterators.
30// This could be implemented by checking if 'end >= start + theoretical_max_diff' when 'max_diff > theoretical_max_diff'.
31// Unfortunately, this causes the most recent Clang to emit a warning when 'start' and 'end' are pointers to an array of objects of size > 2,
32// because it knows that 'theoretical_max_diff' cannot be allocated when ptrdiff_t is a signed version of size_t.
33// It's not clear how we can avoid this warning as general iterators might have a smaller difference type that wouldn't hit such limitations.
34//
35// In addition, a safe ptrdiff() can't do much compile-time trickery to skip the run-time checks, at least not beyond what is already in can_ptrdiff().
36// This is problematic for performance as our safe ptrdiff() may run in a tight loop.
37// By comparison, can_ptrdiff() only needs to be run once to protect all subsequent differences.
38// This comes at the theoretical cost of more false-positive errors if the differences could otherwise fit,
39// but it's hard to imagine a case where we could guarantee that 'end - start' would never reach 'max_diff'... because then we could just set a lower 'max_diff'.
40
41}
42
43#endif
Create compile-time attestations.
Sanitize sizes to avoid integer overflow.
Definition arithmetic.hpp:16
constexpr bool check_overflow(Value_ x)
Definition attest.hpp:178