From beb85cc662beda891989872b90bfd2a95e3c7a5a Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Tue, 7 Nov 2017 14:24:56 +0100 Subject: add warning control macro set 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 --- src/vnet/bfd/bfd_cli.c | 14 ++----- src/vppinfra/warnings.h | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 src/vppinfra/warnings.h diff --git a/src/vnet/bfd/bfd_cli.c b/src/vnet/bfd/bfd_cli.c index a533bb74ea5..0e73172b7cb 100644 --- a/src/vnet/bfd/bfd_cli.c +++ b/src/vnet/bfd/bfd_cli.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -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 index 00000000000..61dcc44f95a --- /dev/null +++ b/src/vppinfra/warnings.h @@ -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__ */ -- cgit 1.2.3-korg