Fix: Pointers are rejected by integer element compile time assertion for array and...
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 20 May 2022 16:00:08 +0000 (12:00 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 20 May 2022 18:22:26 +0000 (14:22 -0400)
commit 2df82195d140b ("Add compile time assertion that array and
sequence have integer elements") introduced a check to validate that
sequences and arrays only contain integers. This was meant to refuse
arrays of double/float which are not supported.

However, as a side-effect, this also refuses arrays and sequences of
pointers, which were accepted prior to lttng-ust 2.13.

Introduce a lttng_ust_is_pointer_type() and use it in the array/sequence
type validation. The trick here is to use the fact that a difference
between two pointers in C is an integer. Therefore, we can validate that
an argument type is a pointer similarly to C++ is_pointer.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fixes: #1355
Change-Id: I7c96d24ab68fb711f85eccdb781a3c513b45c5dc

include/lttng/ust-utils.h
tests/unit/ust-utils/ust-utils-common.h

index cbd1f66adeef8cc530afbc8217942ef9a8c1352d..25b8c7fdb835d55c9f815278c4c2aa1386c1a648 100644 (file)
                __builtin_types_compatible_p(type, unsigned long long))
 #endif
 
+/**
+ * lttng_ust_is_pointer_type - check if type is a pointer
+ *
+ * Returns true if the type of @type is a pointer.
+ */
+#if defined(__cplusplus)
+#define lttng_ust_is_pointer_type(type) (std::is_pointer<type>::value)
+#else
+/* The difference between two pointers is an integer. */
+#define lttng_ust_is_pointer_type(type) \
+       (lttng_ust_is_integer_type(typeof(((type)0 - (type)0))) && !lttng_ust_is_integer_type(type))
+#endif
+
+
 /**
  * lttng_ust_field_array_element_type_is_supported -
  *
  * Adds a compilation assertion that array and sequence fields declared by the
- * user are of an integral type.
+ * user are of an integral or pointer type.
  */
 #define lttng_ust_field_array_element_type_is_supported(type, item) \
-               lttng_ust_static_assert(lttng_ust_is_integer_type(type), \
-                       "Non-integer type `" #item "` not supported as element of LTTNG_UST_FIELD_ARRAY or LTTNG_UST_FIELD_SEQUENCE", \
+               lttng_ust_static_assert(lttng_ust_is_integer_type(type) || lttng_ust_is_pointer_type(type), \
+                       "Non-integer, non-pointer type `" #item "` not supported as element of LTTNG_UST_FIELD_ARRAY or LTTNG_UST_FIELD_SEQUENCE", \
                        Non_integer_type__##item##__not_supported_as_element_of_LTTNG_UST_FIELD_ARRAY_or_LTTNG_UST_FIELD_SEQUENCE)
 
 
index 0792a10e2f9d97c8d1655b6d805c8a4dbdd638a6..0dd15d1975dcfcb8bb3448764c66b959f45cda15 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "tap.h"
 
-#define NUM_TESTS 60
+#define NUM_TESTS 94
 
 static
 void test_ust_stringify(void)
@@ -116,6 +116,61 @@ void test_ust_is_integer_type(void)
        ok_is_not_integer_type(void *);
 }
 
+#define ok_is_pointer_type(_type) \
+       ok(lttng_ust_is_pointer_type(_type) == true, "lttng_ust_is_pointer_type - '" lttng_ust_stringify(_type) "' is a pointer")
+
+#define ok_is_not_pointer_type(_type) \
+       ok(lttng_ust_is_pointer_type(_type) == false, "lttng_ust_is_pointer_type - '" lttng_ust_stringify(_type) "' is not a pointer")
+
+struct dummy {
+       int a;
+};
+
+static
+void test_ust_is_pointer_type(void)
+{
+       ok_is_not_pointer_type(char);
+       ok_is_not_pointer_type(short);
+       ok_is_not_pointer_type(int);
+       ok_is_not_pointer_type(long);
+       ok_is_not_pointer_type(long long);
+
+       ok_is_not_pointer_type(signed char);
+       ok_is_not_pointer_type(signed short);
+       ok_is_not_pointer_type(signed int);
+       ok_is_not_pointer_type(signed long);
+       ok_is_not_pointer_type(signed long long);
+
+       ok_is_not_pointer_type(unsigned char);
+       ok_is_not_pointer_type(unsigned short);
+       ok_is_not_pointer_type(unsigned int);
+       ok_is_not_pointer_type(unsigned long);
+       ok_is_not_pointer_type(unsigned long long);
+
+       ok_is_not_pointer_type(int8_t);
+       ok_is_not_pointer_type(int16_t);
+       ok_is_not_pointer_type(int32_t);
+       ok_is_not_pointer_type(int64_t);
+       ok_is_not_pointer_type(intmax_t);
+
+       ok_is_not_pointer_type(uint8_t);
+       ok_is_not_pointer_type(uint16_t);
+       ok_is_not_pointer_type(uint32_t);
+       ok_is_not_pointer_type(uint64_t);
+       ok_is_not_pointer_type(uintmax_t);
+
+       ok_is_not_pointer_type(float);
+       ok_is_not_pointer_type(double);
+       ok_is_not_pointer_type(long double);
+
+       ok_is_pointer_type(void *);
+       ok_is_pointer_type(void **);
+       ok_is_pointer_type(struct dummy *);
+       ok_is_pointer_type(int *);
+       ok_is_pointer_type(float *);
+       ok_is_pointer_type(double *);
+}
+
 int main(void)
 {
        plan_tests(NUM_TESTS);
@@ -123,6 +178,7 @@ int main(void)
        test_ust_stringify();
        test_ust_is_signed();
        test_ust_is_integer_type();
+       test_ust_is_pointer_type();
 
        return exit_status();
 }
This page took 0.026504 seconds and 4 git commands to generate.