diff --git a/include/criterion/internal/assert/op.h b/include/criterion/internal/assert/op.h index 98271bcb..470ccebb 100644 --- a/include/criterion/internal/assert/op.h +++ b/include/criterion/internal/assert/op.h @@ -205,7 +205,7 @@ #define CRI_ASSERT_OP_TYPE_TAGGED(Type, Var, Name, MkNode, Val) Type #define CRI_ASSERT_OP_TYPE_SINGLE(Type, Var, Name, MkNode, Val) Type -#define CRI_ASSERT_OP_ARRTYPE_TAGGED(Type, Var, Name, MkNode, Val) Type * +#define CRI_ASSERT_OP_ARRTYPE_TAGGED(Type, Var, Name, MkNode, Val) Type const * #define CRI_ASSERT_OP_ARRTYPE_SINGLE(Type, Var, Name, MkNode, Val) Type #define CRI_ASSERT_OPKIND(Kind, Type, Var, Name, MkNode, Val) Kind diff --git a/include/criterion/internal/assert/tag.h b/include/criterion/internal/assert/tag.h index 27bf879d..2535a4b9 100644 --- a/include/criterion/internal/assert/tag.h +++ b/include/criterion/internal/assert/tag.h @@ -36,6 +36,8 @@ #define CRI_ASSERT_TYPE_TAG(Tag) CR_EXPAND(CRI_ASSERT_TYPE_TAG_(Tag)) #define CRI_ASSERT_TYPE_TAG_(Tag) CRI_IF_DEFINED_NODEFER(CRI_ASSERT_TEST_TAG_ ## Tag, CR_VA_HEAD(CRI_ASSERT_TYPE_TAG_ ## Tag), , CRI_ASSERT_TYPE_TAG_UNKNOWN, (Tag)) +#define CRI_ASSERT_MUT_TYPE_TAG(Tag) CR_EXPAND(CRI_ASSERT_MUT_TYPE_TAG_(Tag)) +#define CRI_ASSERT_MUT_TYPE_TAG_(Tag) CRI_IF_DEFINED_NODEFER(CRI_ASSERT_TEST_TAG_ ## Tag, CR_VA_HEAD(CRI_ASSERT_MUT_TYPE_TAG_ ## Tag), , CRI_ASSERT_TYPE_TAG_UNKNOWN, (Tag)) #define CRI_USER_TAG_ID(Id, Tag) CR_CONCAT(CR_CONCAT(cr_user_, CRI_ASSERT_TYPE_TAG_ID(Tag)), _ ## Id) @@ -127,7 +129,7 @@ #define CRI_ASSERT_TEST_TAG_ptr , #define CRI_ASSERT_TEST_TAGC_ptr() , -#define CRI_ASSERT_TYPE_TAG_ptr void *, +#define CRI_ASSERT_TYPE_TAG_ptr const void *, #define CRI_ASSERT_TYPE_TAG_ID_ptr ptr, #define CRI_ASSERT_TEST_TAG_str , @@ -135,7 +137,8 @@ #ifdef __cplusplus # define CRI_ASSERT_TYPE_TAG_str std::string, #else -# define CRI_ASSERT_TYPE_TAG_str char *, +# define CRI_ASSERT_TYPE_TAG_str const char *, +# define CRI_ASSERT_MUT_TYPE_TAG_str char *, #endif #define CRI_ASSERT_TYPE_TAG_ID_str str, @@ -144,7 +147,8 @@ #ifdef __cplusplus # define CRI_ASSERT_TYPE_TAG_wcs std::wstring, #else -# define CRI_ASSERT_TYPE_TAG_wcs wchar_t *, +# define CRI_ASSERT_TYPE_TAG_wcs const wchar_t *, +# define CRI_ASSERT_MUT_TYPE_TAG_wcs wchar_t *, #endif #define CRI_ASSERT_TYPE_TAG_ID_wcs wcs, @@ -195,19 +199,19 @@ #define CRI_ASSERT_DECLARE_NATIVE_CMP_FN(Tag) \ static inline int CRI_USER_TAG_ID(lt, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *actual, \ - CRI_ASSERT_TYPE_TAG(Tag) *expected) \ + CRI_ASSERT_TYPE_TAG(Tag) const *actual, \ + CRI_ASSERT_TYPE_TAG(Tag) const *expected) \ { \ return *actual < *expected; \ } \ static inline int CRI_USER_TAG_ID(eq, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *actual, \ - CRI_ASSERT_TYPE_TAG(Tag) *expected) \ + CRI_ASSERT_TYPE_TAG(Tag) const *actual, \ + CRI_ASSERT_TYPE_TAG(Tag) const *expected) \ { \ return *actual == *expected; \ } \ static inline int CRI_USER_TAG_ID(zero, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *val) \ + CRI_ASSERT_TYPE_TAG(Tag) const *val) \ { \ return !*val; \ } @@ -215,22 +219,24 @@ #define CRI_ASSERT_DECLARE_NATIVE_FN(Tag, Fmt) \ CRI_ASSERT_DECLARE_NATIVE_CMP_FN(Tag) \ static inline char *CRI_USER_TAG_ID(tostr, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *e) \ + CRI_ASSERT_TYPE_TAG(Tag) const *e) \ { \ char *str = NULL; \ cr_asprintf(&str, "%" Fmt, *e); \ return str; \ } -#define CRI_ASSERT_DECLARE_STR_FN(Tag, Prefix, Fmt) \ - CR_API int CRI_USER_TAG_ID(lt, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *actual, \ - CRI_ASSERT_TYPE_TAG(Tag) *expected); \ - CR_API int CRI_USER_TAG_ID(eq, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *actual, \ - CRI_ASSERT_TYPE_TAG(Tag) *expected); \ - CR_API int CRI_USER_TAG_ID(zero, Tag)(CRI_ASSERT_TYPE_TAG(Tag) *val); \ - CR_API char *CRI_USER_TAG_ID(tostr, Tag)(CRI_ASSERT_TYPE_TAG(Tag) *e); +#define CRI_ASSERT_DECLARE_STR_FN(Tag, Prefix, Fmt) \ + CR_API int CRI_USER_TAG_ID(lt, Tag)( \ + CRI_ASSERT_TYPE_TAG(Tag) const *actual, \ + CRI_ASSERT_TYPE_TAG(Tag) const *expected); \ + CR_API int CRI_USER_TAG_ID(eq, Tag)( \ + CRI_ASSERT_TYPE_TAG(Tag) const *actual, \ + CRI_ASSERT_TYPE_TAG(Tag) const *expected); \ + CR_API int CRI_USER_TAG_ID(zero, Tag)( \ + CRI_ASSERT_TYPE_TAG(Tag) const *val); \ + CR_API char *CRI_USER_TAG_ID(tostr, Tag)( \ + CRI_ASSERT_TYPE_TAG(Tag) const *e); #ifndef __cplusplus # include @@ -287,7 +293,7 @@ CRI_ASSERT_DECLARE_NATIVE_CMP_FN(iptr) CRI_ASSERT_DECLARE_NATIVE_CMP_FN(uptr) CRI_ASSERT_DECLARE_NATIVE_CMP_FN(ptr) -static inline char *CRI_USER_TAG_ID(tostr, iptr)(intptr_t *e) +static inline char *CRI_USER_TAG_ID(tostr, iptr)(const intptr_t *e) { uintptr_t absptr = (uintptr_t) *e; if (absptr > (uintptr_t)INTPTR_MAX) @@ -298,14 +304,14 @@ static inline char *CRI_USER_TAG_ID(tostr, iptr)(intptr_t *e) return str; } -static inline char *CRI_USER_TAG_ID(tostr, uptr)(uintptr_t *e) +static inline char *CRI_USER_TAG_ID(tostr, uptr)(const uintptr_t *e) { char *str = NULL; cr_asprintf(&str, "0x%" CRI_PRIxPTR, *e); return str; } -static inline char *CRI_USER_TAG_ID(tostr, ptr)(void **e) +static inline char *CRI_USER_TAG_ID(tostr, ptr)(const void **e) { char *str = NULL; cr_asprintf(&str, "0x%" CRI_PRIxPTR, (uintptr_t) *e); diff --git a/include/criterion/internal/assert/tostr.h b/include/criterion/internal/assert/tostr.h index 498a0363..59d92a6a 100644 --- a/include/criterion/internal/assert/tostr.h +++ b/include/criterion/internal/assert/tostr.h @@ -115,7 +115,7 @@ inline ostream &operator<<(ostream &s, const std::nullptr_t &ptr) return s; } -inline ostream &operator<<(ostream &s, void *const &ptr) +inline ostream &operator<<(ostream &s, const void *const &ptr) { if (!ptr) return ::criterion::internal::stream_override::operator<<(s, nullptr); diff --git a/include/criterion/new/stream.h b/include/criterion/new/stream.h index c5ae0a11..52905248 100644 --- a/include/criterion/new/stream.h +++ b/include/criterion/new/stream.h @@ -74,8 +74,8 @@ CR_BEGIN_C_API CR_API void cr_stream_init(struct cr_stream *s); CR_API void cr_stream_close(struct cr_stream *s); -CR_API int cr_user_stream_eq(struct cr_stream *s1, struct cr_stream *s2); -CR_API int cr_user_stream_lt(struct cr_stream *s1, struct cr_stream *s2); +CR_API int cr_user_stream_eq(const struct cr_stream *s1, const struct cr_stream *s2); +CR_API int cr_user_stream_lt(const struct cr_stream *s1, const struct cr_stream *s2); CR_API char *cr_user_stream_tostr(const struct cr_stream *s); CR_END_C_API diff --git a/samples/asserts.c b/samples/asserts.c index 78d39a08..9d6b6265 100644 --- a/samples/asserts.c +++ b/samples/asserts.c @@ -83,12 +83,12 @@ struct dummy_struct { }; /* We need to provide basic functions for our dummy struct */ -int cr_user_dummy_struct_eq(struct dummy_struct *a, struct dummy_struct *b) +int cr_user_dummy_struct_eq(const struct dummy_struct *a, const struct dummy_struct *b) { return a->a == b->a && a->b == b->b; } -char *cr_user_dummy_struct_tostr(struct dummy_struct *d) +char *cr_user_dummy_struct_tostr(const struct dummy_struct *d) { char *out; @@ -97,8 +97,8 @@ char *cr_user_dummy_struct_tostr(struct dummy_struct *d) } Test(asserts, array) { - int arr1[] = { 1, 2, 3, 4 }; - int arr2[] = { 4, 3, 2, 1 }; + static const int arr1[] = { 1, 2, 3, 4 }; + static const int arr2[] = { 4, 3, 2, 1 }; /* For primitive types we can compare their byte-to-byte representation */ struct cr_mem mem_arr1 = { .data = arr1, .size = 4 * sizeof (int) }; diff --git a/src/capi/specifiers.c b/src/capi/specifiers.c index deb14bf9..5bdaa2e8 100644 --- a/src/capi/specifiers.c +++ b/src/capi/specifiers.c @@ -33,25 +33,26 @@ /* *INDENT-OFF* */ #define CRI_ASSERT_DEFINE_STR_FN(Tag, Prefix, Fmt) \ int CRI_USER_TAG_ID(lt, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *actual, \ - CRI_ASSERT_TYPE_TAG(Tag) *expected) \ + CRI_ASSERT_TYPE_TAG(Tag) const *actual, \ + CRI_ASSERT_TYPE_TAG(Tag) const *expected) \ { \ return Tag ## cmp(*actual, *expected) < 0; \ } \ int CRI_USER_TAG_ID(eq, Tag)( \ - CRI_ASSERT_TYPE_TAG(Tag) *actual, \ - CRI_ASSERT_TYPE_TAG(Tag) *expected) \ + CRI_ASSERT_TYPE_TAG(Tag) const *actual, \ + CRI_ASSERT_TYPE_TAG(Tag) const *expected) \ { \ return !Tag ## cmp(*actual, *expected); \ } \ - int CRI_USER_TAG_ID(zero, Tag)(CRI_ASSERT_TYPE_TAG(Tag) *val) \ + int CRI_USER_TAG_ID(zero, Tag)(CRI_ASSERT_TYPE_TAG(Tag) const *val) \ { \ return !Tag ## len(*val); \ } \ - char *CRI_USER_TAG_ID(tostr, Tag)(CRI_ASSERT_TYPE_TAG(Tag) *e) \ + char *CRI_USER_TAG_ID(tostr, Tag)(CRI_ASSERT_TYPE_TAG(Tag) const *e) \ { \ - CRI_ASSERT_TYPE_TAG(Tag) cri_dup = Tag ## dup(*e); \ - CRI_ASSERT_TYPE_TAG(Tag) cri_line = cri_ ## Tag ## tokc(cri_dup, '\n'); \ + CRI_ASSERT_MUT_TYPE_TAG(Tag) cri_dup = Tag ## dup(*e); \ + CRI_ASSERT_MUT_TYPE_TAG(Tag) cri_line; \ + cri_line = cri_ ## Tag ## tokc(cri_dup, '\n'); \ \ char *cri_str = NULL; \ size_t cri_off = 0; \ diff --git a/src/capi/stream.c b/src/capi/stream.c index 54a03fff..c40cc95b 100644 --- a/src/capi/stream.c +++ b/src/capi/stream.c @@ -27,7 +27,8 @@ #include "criterion/new/stream.h" #include "string/xxd.h" -static int streams_eval_cmp(struct cr_stream *m1, struct cr_stream *m2) +static int streams_eval_cmp(const struct cr_stream *m1, + const struct cr_stream *m2) { /* It doesn't make sense to compare consumed streams, but it still happens in some case within an assertion. It's best to provide @@ -80,12 +81,12 @@ static int streams_eval_cmp(struct cr_stream *m1, struct cr_stream *m2) return cmp; } -int cr_user_stream_eq(struct cr_stream *m1, struct cr_stream *m2) +int cr_user_stream_eq(const struct cr_stream *m1, const struct cr_stream *m2) { return !streams_eval_cmp(m1, m2); } -int cr_user_stream_lt(struct cr_stream *m1, struct cr_stream *m2) +int cr_user_stream_lt(const struct cr_stream *m1, const struct cr_stream *m2) { return streams_eval_cmp(m1, m2) < 0; } diff --git a/test/full/bug521.c b/test/full/bug521.c new file mode 100644 index 00000000..6a360d2a --- /dev/null +++ b/test/full/bug521.c @@ -0,0 +1,19 @@ +#include +#include + +Test(bug521, str) { + static const char *const foo = "foo"; + cr_assert(eq(str, foo, "foo")); + cr_assert(ne(str, foo, "oof")); +} + +Test(bug521, wcs) { + static const wchar_t *const foo = L"foo"; + cr_assert(eq(wcs, foo, L"foo")); + cr_assert(ne(wcs, foo, L"oof")); +} + +Test(bug521, ptr) { + static const char *const foo = "foo"; + cr_assert(eq(ptr, foo, foo)); +} \ No newline at end of file diff --git a/test/full/failmessages.c b/test/full/failmessages.c index b10cc4f9..3c1ba5fe 100644 --- a/test/full/failmessages.c +++ b/test/full/failmessages.c @@ -8,17 +8,17 @@ struct dummy_struct { }; /* We need to provide basic functions for our dummy struct */ -int cr_user_dummy_struct_eq(struct dummy_struct *a, struct dummy_struct *b) +int cr_user_dummy_struct_eq(const struct dummy_struct *a, const struct dummy_struct *b) { return a->a == b->a && a->b == b->b; } -int cr_user_dummy_struct_zero(struct dummy_struct *a) +int cr_user_dummy_struct_zero(const struct dummy_struct *a) { return !a->a && !a->b; } -char *cr_user_dummy_struct_tostr(struct dummy_struct *d) +char *cr_user_dummy_struct_tostr(const struct dummy_struct *d) { char *out; diff --git a/test/full/meson.build b/test/full/meson.build index d64015f3..34702c2b 100644 --- a/test/full/meson.build +++ b/test/full/meson.build @@ -8,6 +8,7 @@ full_tests = [ # bug-specific programs 'bug463.c', + 'bug521.c', ] if get_option('theories').enabled()