add warning control macro set 66/9266/2
authorGabriel Ganne <gabriel.ganne@enea.com>
Tue, 7 Nov 2017 13:24:56 +0000 (14:24 +0100)
committerDamjan Marion <dmarion.lists@gmail.com>
Fri, 10 Nov 2017 20:28:45 +0000 (20:28 +0000)
Add a way to toggle on and off a warning for a specific section of code.
This supports clang and gcc, and has no effect for any other compilers.

This follows commit bfc29ba442dbb65599f29fe5aa44c6219ed0d3a8 and
provides a generic way to handle warnings in such corner cases.

To disable a warning enabled by "-Wsome-warning" for a specific code:
  WARN_OFF(some-warning)  // disable compiler warning
  ; /* some code */
  WARN_ON(some-warning)   // enable the warning again

Change-Id: I0101caa0aa775e2b905c7b3b5fef3bbdce281673
Signed-off-by: Gabriel Ganne <gabriel.ganne@enea.com>
src/vnet/bfd/bfd_cli.c
src/vppinfra/warnings.h [new file with mode: 0644]

index a533bb7..0e73172 100644 (file)
@@ -20,6 +20,7 @@
 #include <vlib/vlib.h>
 #include <vlib/cli.h>
 #include <vppinfra/format.h>
+#include <vppinfra/warnings.h>
 #include <vnet/api_errno.h>
 #include <vnet/ip/format.h>
 #include <vnet/bfd/bfd_api.h>
@@ -385,20 +386,11 @@ static const unsigned optional = 0;
       have_##n = 1;                            \
     }
 
-#if __GNUC__ >= 6
-#define PRAGMA_STR1 \
-  _Pragma ("GCC diagnostic ignored \"-Wtautological-compare\"");
-#define PRAGMA_STR2 _Pragma ("GCC diagnostic pop");
-#else
-#define PRAGMA_STR1
-#define PRAGMA_STR2
-#endif
-
 #define CHECK_MANDATORY(t, n, s, r, ...)                                  \
-  PRAGMA_STR1                                                             \
+WARN_OFF(tautological-compare)                                            \
   if (mandatory == r && !have_##n)                                        \
     {                                                                     \
-      PRAGMA_STR2                                                         \
+      WARN_ON(tautological-compare)                                       \
       ret = clib_error_return (0, "Required parameter `%s' missing.", s); \
       goto out;                                                           \
     }
diff --git a/src/vppinfra/warnings.h b/src/vppinfra/warnings.h
new file mode 100644 (file)
index 0000000..61dcc44
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+ */
+
+#ifndef __included_warnings_h__
+#define __included_warnings_h__
+
+/* Macros to check compiler version */
+#if defined(__GNUC__)
+#define COMPILER_VERSION_GTE(major, minor) \
+  (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
+#elif defined(__clang__)
+#define COMPILER_VERSION_GTE(major, minor) \
+  (__clang_major__ > (major) ||            \
+   (__clang_major__ == (major) && __clang_minor__ >= (minor)))
+#else /* disable all warning customization for all other compilers */
+#define COMPILER_VERSION_GTE(maj, min) 0
+#endif
+
+/* '#' needs to preceed a macro parameter */
+#define WARN_TOSTR(x) #x
+
+/*
+ * Macros to toggle off/on warnings
+ *
+ * Start by silenging pragma warnings so that we can explicitely silence
+ * a warning introduced on some compiler version and not get a warning on older
+ * versions of that same compiler.
+ *
+ * gcc corresponding warnign is "Wpargma"
+ * clang corresponding warnign is "Wunknown-warning-option"
+ *
+ * For example, Wtautological-compare is introduced in gcc-6 and this would
+ * trigger a Wpargma warning on gcc-5.
+ *
+ * Example usage to disable -Wtautological-compare warning:
+ *   WARN_OFF(tautological-compare)
+ *   if (...) {
+ *   WARN_ON(tautological-compare)
+ *     ; // conditional code
+ *   }
+ */
+#if defined(__GNUC__) && COMPILER_VERSION_GTE(4, 6)
+/*
+ * GCC option to locally ignore warning was introduced in gcc-4.6
+ * gcc.gnu.org/gcc-4.6/changes.html
+ */
+#define WARN_PRAGMA(x) _Pragma (WARN_TOSTR (GCC diagnostic x))
+#define WARN_OFF(x)                                    \
+  WARN_PRAGMA (push) WARN_PRAGMA (ignored "-Wpragmas") \
+  WARN_PRAGMA (push) WARN_PRAGMA (ignored WARN_TOSTR (-W##x))
+#define WARN_ON(x)  \
+  WARN_PRAGMA (pop) \
+  WARN_PRAGMA (pop)
+
+#elif defined(__clang__) && COMPILER_VERSION_GTE(3, 3)
+/*
+ * clang option to locally ignore warning was introduced in clang-3.3
+ * releases.llvm.org/3.3/tools/clang/docs/UsersManual.html#controlling-diagnostics-via-pragmas
+ */
+#define WARN_PRAGMA(x) _Pragma (WARN_TOSTR (clang diagnostic x))
+#define WARN_OFF(x)                                                   \
+  WARN_PRAGMA (push) WARN_PRAGMA (ignored "-Wunknown-warning-option") \
+  WARN_PRAGMA (push) WARN_PRAGMA (ignored WARN_TOSTR (-W##x))
+#define WARN_ON(x)  \
+  WARN_PRAGMA (pop) \
+  WARN_PRAGMA (pop)
+#else
+/* Ignore WARN_* instruction for all other compilers */
+#define WARN_OFF(x)
+#define WARN_ON(x)
+#endif
+
+/*
+ * Clang supports a wider range of warnings than gcc.
+ * Use those specific macros for the warnings that are only supported by clang
+ */
+#ifdef __clang__
+#define WARN_OFF_CLANG(x) WARN_OFF (x)
+#define WARN_ON_CLANG(x) WARN_ON (x)
+#else
+#define WARN_OFF_CLANG(x)
+#define WARN_ON_CLANG(x)
+#endif
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
+#endif /* __included_warnings_h__ */