base: avoid (NULL + 0) in slice functions Fixes #178
diff --git a/internal/cgen/base/fundamental-public.h b/internal/cgen/base/fundamental-public.h index 0ad1ebc..68ca4ec 100644 --- a/internal/cgen/base/fundamental-public.h +++ b/internal/cgen/base/fundamental-public.h
@@ -1466,7 +1466,7 @@ static inline wuffs_base__slice_u8 // wuffs_base__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) { wuffs_base__slice_u8 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1474,7 +1474,7 @@ static inline wuffs_base__slice_u16 // wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) { wuffs_base__slice_u16 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1482,7 +1482,7 @@ static inline wuffs_base__slice_u32 // wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) { wuffs_base__slice_u32 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1490,7 +1490,7 @@ static inline wuffs_base__slice_u64 // wuffs_base__make_slice_u64_ij(uint64_t* ptr, size_t i, size_t j) { wuffs_base__slice_u64 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1631,7 +1631,12 @@ static inline wuffs_base__slice_u8 // wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) { if ((i <= SIZE_MAX) && (i <= s.len)) { - return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i))); + // The "i ? (s.ptr + i) : s.ptr" expression is equivalent to the plain + // "s.ptr + i", except for the fact that in C (prior to C29), but not in + // C++, "NULL + 0" is, technically, undefined behavior (and triggers + // ubsan). See C29 N3322 and https://reviews.llvm.org/D67122 + return wuffs_base__make_slice_u8(i ? (s.ptr + i) : s.ptr, + ((size_t)(s.len - i))); } return wuffs_base__empty_slice_u8(); } @@ -1655,7 +1660,12 @@ uint64_t i, uint64_t j) { if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) { - return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i))); + // The "i ? (s.ptr + i) : s.ptr" expression is equivalent to the plain + // "s.ptr + i", except for the fact that in C (prior to C29), but not in + // C++, "NULL + 0" is, technically, undefined behavior (and triggers + // ubsan). See C29 N3322 and https://reviews.llvm.org/D67122 + return wuffs_base__make_slice_u8(i ? (s.ptr + i) : s.ptr, + ((size_t)(j - i))); } return wuffs_base__empty_slice_u8(); }
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c index 162f441..8082699 100644 --- a/release/c/wuffs-unsupported-snapshot.c +++ b/release/c/wuffs-unsupported-snapshot.c
@@ -1752,7 +1752,7 @@ static inline wuffs_base__slice_u8 // wuffs_base__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) { wuffs_base__slice_u8 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1760,7 +1760,7 @@ static inline wuffs_base__slice_u16 // wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) { wuffs_base__slice_u16 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1768,7 +1768,7 @@ static inline wuffs_base__slice_u32 // wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) { wuffs_base__slice_u32 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1776,7 +1776,7 @@ static inline wuffs_base__slice_u64 // wuffs_base__make_slice_u64_ij(uint64_t* ptr, size_t i, size_t j) { wuffs_base__slice_u64 ret; - ret.ptr = ptr ? (ptr + i) : NULL; + ret.ptr = i ? (ptr + i) : ptr; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1917,7 +1917,12 @@ static inline wuffs_base__slice_u8 // wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) { if ((i <= SIZE_MAX) && (i <= s.len)) { - return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i))); + // The "i ? (s.ptr + i) : s.ptr" expression is equivalent to the plain + // "s.ptr + i", except for the fact that in C (prior to C29), but not in + // C++, "NULL + 0" is, technically, undefined behavior (and triggers + // ubsan). See C29 N3322 and https://reviews.llvm.org/D67122 + return wuffs_base__make_slice_u8(i ? (s.ptr + i) : s.ptr, + ((size_t)(s.len - i))); } return wuffs_base__empty_slice_u8(); } @@ -1941,7 +1946,12 @@ uint64_t i, uint64_t j) { if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) { - return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i))); + // The "i ? (s.ptr + i) : s.ptr" expression is equivalent to the plain + // "s.ptr + i", except for the fact that in C (prior to C29), but not in + // C++, "NULL + 0" is, technically, undefined behavior (and triggers + // ubsan). See C29 N3322 and https://reviews.llvm.org/D67122 + return wuffs_base__make_slice_u8(i ? (s.ptr + i) : s.ptr, + ((size_t)(j - i))); } return wuffs_base__empty_slice_u8(); }