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 "generics.hpp"
7#include "utils.hpp"
8#include "cast.hpp"
9
15namespace sanisizer {
16
20template<typename Iterator_, typename MaxDiff_>
21constexpr bool can_ptrdiff(MaxDiff_ max_diff) {
22 typedef I<decltype(std::declval<Iterator_>() - std::declval<Iterator_>())> Diff;
23 check_overflow<Diff>(max_diff);
24 return true;
25}
30// It is tempting to write a ptrdiff() function that checks each subtraction for overflow/wraparound given 'start' and 'end' iterators.
31// This could be implemented by checking if 'end >= start + theoretical_max_diff' when 'max_diff > theoretical_max_diff'.
32// 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,
33// because it knows that 'theoretical_max_diff' cannot be allocated when ptrdiff_t is a signed version of size_t.
34// 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.
35//
36// 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().
37// This is problematic for performance as our safe ptrdiff() may run in a tight loop.
38// By comparison, can_ptrdiff() only needs to be run once to protect all subsequent differences.
39// This comes at the theoretical cost of more false-positive errors if the differences could otherwise fit,
40// 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'.
41
42}
43
44#endif
Safe casts of integer size.
Generics for operating on integer representations.
Sanitize sizes to avoid integer overflow.
Definition Bounded.hpp:15