Build fix: unknown warning -Wduplicated-branches
[lttng-tools.git] / src / common / macros.hpp
index 49f163b42fb5a6c81cc3906f9016a06fac6383a2..cfe6eb5289d637ef1f1d1ddafe1b2f808a78535a 100644 (file)
@@ -15,6 +15,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <memory>
+#include <pthread.h>
 #include <type_traits>
 
 /*
@@ -63,7 +65,19 @@ void *zmalloc_internal(size_t size)
 template <typename T>
 struct can_malloc
 {
+       /*
+        * gcc versions before 5.0 lack some type traits defined in C++11.
+        * Since in this instance we use the trait to prevent misuses
+        * of malloc (and statically assert) and not to generate different
+        * code based on this property, simply set value to true and allow
+        * the code to compile. Anyone using a contemporary compiler will
+        * catch the error.
+        */
+#if __GNUG__ && __GNUC__ < 5
+       static constexpr bool value = true;
+#else
        static constexpr bool value = std::is_trivially_constructible<T>::value;
+#endif
 };
 
 /*
@@ -136,24 +150,83 @@ T *malloc(size_t size)
  */
 
 template<typename T>
-struct is_pod_or_void
+struct can_free
 {
-       static constexpr bool value = std::is_pod<T>::value || std::is_void<T>::value;
+       /*
+        * gcc versions before 5.0 lack some type traits defined in C++11.
+        * Since in this instance we use the trait to prevent misuses
+        * of free (and statically assert) and not to generate different
+        * code based on this property, simply set value to true and allow
+        * the code to compile. Anyone using a contemporary compiler will
+        * catch the error.
+        */
+#if __GNUG__ && __GNUC__ < 5
+       static constexpr bool value = true;
+#else
+       static constexpr bool value = std::is_trivially_destructible<T>::value || std::is_void<T>::value;
+#endif
 };
 
-template<typename T, typename = typename std::enable_if<!is_pod_or_void<T>::value>::type>
+template<typename T, typename = typename std::enable_if<!can_free<T>::value>::type>
 void free(T *p) = delete;
 
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(array)   (sizeof(array) / (sizeof((array)[0])))
+template<typename T>
+struct can_memset
+{
+       static constexpr bool value = std::is_pod<T>::value || std::is_void<T>::value;
+};
+
+template <typename T, typename = typename std::enable_if<!can_memset<T>::value>::type>
+void *memset(T *s, int c, size_t n) = delete;
+
+template<typename T>
+struct can_memcpy
+{
+       /*
+        * gcc versions before 5.0 lack some type traits defined in C++11.
+        * Since in this instance we use the trait to prevent misuses
+        * of memcpy (and statically assert) and not to generate different
+        * code based on this property, simply set value to true and allow
+        * the code to compile. Anyone using a contemporary compiler will
+        * catch the error.
+        */
+#if __GNUG__ && __GNUC__ < 5
+       static constexpr bool value = true;
+#else
+       static constexpr bool value = std::is_trivially_copyable<T>::value;
 #endif
+};
+
+template <typename T, typename U,
+               typename = typename std::enable_if<!can_memcpy<T>::value>::type,
+               typename = typename std::enable_if<!can_memcpy<U>::value>::type>
+void *memcpy(T *d, const U *s, size_t n) = delete;
+
+template<typename T>
+struct can_memmove
+{
+       /*
+        * gcc versions before 5.0 lack some type traits defined in C++11.
+        * Since in this instance we use the trait to prevent misuses
+        * of memmove (and statically assert) and not to generate different
+        * code based on this property, simply set value to true and allow
+        * the code to compile. Anyone using a contemporary compiler will
+        * catch the error.
+        */
+#if __GNUG__ && __GNUC__ < 5
+       static constexpr bool value = true;
+#else
+       static constexpr bool value = std::is_trivially_copyable<T>::value;
+#endif
+};
 
-#ifndef container_of
-#define container_of(ptr, type, member)                                        \
-       ({                                                              \
-               const typeof(((type *)NULL)->member) * __ptr = (ptr);   \
-               (type *)((char *)__ptr - offsetof(type, member));       \
-       })
+template <typename T, typename U,
+               typename = typename std::enable_if<!can_memmove<T>::value>::type,
+               typename = typename std::enable_if<!can_memmove<U>::value>::type>
+void *memmove(T *d, const U *s, size_t n) = delete;
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(array)   (sizeof(array) / (sizeof((array)[0])))
 #endif
 
 #ifndef LTTNG_PACKED
@@ -192,6 +265,9 @@ void free(T *p) = delete;
 # define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
        _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
 # define DIAGNOSTIC_IGNORE_LOGICAL_OP
+# define DIAGNOSTIC_IGNORE_DUPLICATED_BRANCHES
+# define DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
+       _Pragma("GCC diagnostic ignored \"-Winvalid-offsetof\"")
 #else
   /* GCC */
 # define DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT \
@@ -200,6 +276,14 @@ void free(T *p) = delete;
        _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
 # define DIAGNOSTIC_IGNORE_LOGICAL_OP \
        _Pragma("GCC diagnostic ignored \"-Wlogical-op\"")
+#if __GNUG__ && __GNUC__ >= 7
+# define DIAGNOSTIC_IGNORE_DUPLICATED_BRANCHES                         \
+       _Pragma("GCC diagnostic ignored \"-Wduplicated-branches\"")
+#else
+# define DIAGNOSTIC_IGNORE_DUPLICATED_BRANCHES
+#endif /* __GNUG__ && __GNUC__ >= 7 */
+# define DIAGNOSTIC_IGNORE_INVALID_OFFSETOF                            \
+       _Pragma("GCC diagnostic ignored \"-Winvalid-offsetof\"")
 #endif
 
 /* Used to make specific C++ functions to C code. */
@@ -229,4 +313,18 @@ int lttng_strncpy(char *dst, const char *src, size_t dst_len)
        return 0;
 }
 
+namespace lttng {
+namespace utils {
+template <class Parent, class Member>
+Parent *container_of(const Member *member, const Member Parent::*ptr_to_member)
+{
+       const Parent *dummy_parent = nullptr;
+       auto *offset_of_member = reinterpret_cast<const char *>(&(dummy_parent->*ptr_to_member));
+       auto address_of_parent = reinterpret_cast<const char *>(member) - offset_of_member;
+
+       return reinterpret_cast<Parent *>(address_of_parent);
+}
+} /* namespace utils */
+} /* namespace lttng */
+
 #endif /* _MACROS_H */
This page took 0.025232 seconds and 4 git commands to generate.