Handling large volume of boost unit test related warnings with clang-tidy - boost

I'm in the process of setting up a project. I have skeleton tests in place using boost unit-test. Unfortunately a large number of warnings are spawned from the macro expansions. Is there a way to disable these, without have to specify individual line numbers?.
This occurs even when I have a // NOLINT.
An example:
/home/peter/checkouts/canopen-gateway/./unittests/projs/server/exe/testunit-tcp-socket.cpp:12:1: warning: construction of 'end_suite12_registrar12' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
BOOST_AUTO_TEST_SUITE_END() // NOLINT
^
/usr/include/boost/test/unit_test_suite.hpp:62:73: note: expanded from macro 'BOOST_AUTO_TEST_SUITE_END'
#define BOOST_AUTO_TEST_SUITE_END() \
^
/usr/include/boost/test/unit_test_suite.hpp:209:62: note: expanded from macro '\BOOST_AUTO_TU_REGISTRAR'
static boost::unit_test::ut_detail::auto_test_unit_registrar BOOST_JOIN( BOOST_JOIN( test_name, _registrar ), __LINE__ )
^
/usr/include/boost/config/suffix.hpp:544:28: note: expanded from macro 'BOOST_JOIN'
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
^
/usr/include/boost/config/suffix.hpp:545:31: note: expanded from macro 'BOOST_DO_JOIN'
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
^
/usr/include/boost/config/suffix.hpp:546:32: note: expanded from macro 'BOOST_DO_JOIN2'
#define BOOST_DO_JOIN2( X, Y ) X##Y
^
note: expanded from here
/usr/include/boost/test/unit_test_suite_impl.hpp:284:17: note: possibly throwing constructor declared here
explicit auto_test_unit_registrar( int );

You probably didn't paste the entire error message, but somewhere in there should be a line that says
warning: disabled expansion of recursive macro
[-Wdisabled-macro-expansion]
You can disable this by passing -Wno-disabled-macro-expansion to the clang command line.

Try wrapping the offending code thus:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
// your code here
#pragma clang diagnostic pop

Related

Why am i getting the followng error when I called getline() in my C code?

I am getting the following error
rudimentary_calc.c: In function ‘main’:
rudimentary_calc.c:9:6: error: conflicting types for ‘getline’
9 | int getline(char line[], int max) ;
| ^~~~~~~
In file included from rudimentary_calc.c:1:
/usr/include/stdio.h:616:18: note: previous declaration of ‘getline’ was here
616 | extern __ssize_t getline (char **__restrict __lineptr,
| ^~~~~~~
when I ran the following code
#include <stdio.h>
#define maxline 100
int main()
{
double sum, atof(char[]);
char line[maxline];
int getline(char line[], int max) ;
sum = 0;
while (getline(line, maxline) > 0)
printf("\t %g \n", sum += atof(line));
return 0;
}
What am I doing wrong? I am very new to C, so I don't know what went wrong.
Generally, you should not have to declare "built-in" functions as long as you #include the appropriate header files (in this case stdio.h). The compiler is complaining that your declaration is not exactly the same as the one in stdio.h.
The venerable K&R book defines a function named getline. The GNU C library also defines a non-standard function named getline. It is not compatible with the function defined in K&R. It is declared in the standard <stdio.h> header. So there is a name conflict (something that every C programmer has do deal with).
You can instruct GCC to ignore non-standard names found in standard headers. You need to supply a compilation flag such as -std=c99 or -std=c11 or any other std=c<year> flag that yout compiler supports.
Live demo
Always use one of these flags, plus at least -Wall, to compile any C code, including code from K&R. You may encounter some compiler warnings or even errors. This is good. Thy will tell you that there are some code constructs that were good in the days of K&R, but are considered problematic now. You want to know about those. The book is rather old and the best practices and the C language itself have evolved since.

Error installing perl on Win10 using MinGW

If this is the wrong place for this question I apologise and please redirect me to the suitable section.
I'm somewhat rusty on installing from command line, especially on Windows. I decided to install the latest Perl version on my PC, running under Windows 10. I had previously installed it using Strawberry Perl download, but as it was a few versions out of date I decided to remove it and refresh my skills (ha) by installing it manually. I downloaded the lastest Perl release from https://www.perl.org/get.html#win32 and have been reading the README.win32 to make sure I install it correctly.
As I need a compiler, I decided to use Gcc and dmake. I installed and can run them successfully so went back to installing Perl. As per instructions I tried running dmake in the win32 subdirectory in the Perl download folder. Before this I edited makefile.mk, where these variables are uncommented from the Build configuration section:
INST_DRV/INST_TOP (left as is)
INST_VER *= \5.26.0
USE_MULTI *= define
USE_ITHREADS *= define
USE_IMP_SYS *= define
USE_LARGE_FILES *= define
USE_64_BIT_INT *= define
USE_LONG_DOUBLE *= define
DEFAULT_INC_EXCLUDES_DOT *= define
CCTYPE = GCC
GCCWRAPV *=define
CCHOME *= C:\MinGW
(nothing else changed after this)
When I run dmake in the directory, it quickly comes to this error:
gcc -c -I.\include -I. -I.. -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -
D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing
-DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\toke.o ..\toke.c
In file included from ..\perl.h:3220:0,
from ..\toke.c:40:
./win32.h:417:13: error: conflicting types for 'mkstemp'
extern int mkstemp(const char *path);
^~~~~~~
In file included from ..\perl.h:790:0,
from ..\toke.c:40:
c:\mingw\include\stdlib.h:809:30: note: previous definition of 'mkstemp' was here
__cdecl __MINGW_NOTHROW int mkstemp (char *__filename_template)
^~~~~~~
In file included from ..\toke.c:40:0:
..\toke.c: In function 'Perl_filter_add':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1769:28: note: in expansion of macro 'PTR2nat'
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^~~~~~~
..\toke.c:4397:21: note: in expansion of macro 'FPTR2DPTR'
IoANY(datasv) = FPTR2DPTR(void *, funcp); /* stash funcp into spare field */
^~~~~~~~~
..\perl.h:1769:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^
..\toke.c:4397:21: note: in expansion of macro 'FPTR2DPTR'
IoANY(datasv) = FPTR2DPTR(void *, funcp); /* stash funcp into spare field */
^~~~~~~~~
..\toke.c: In function 'Perl_filter_del':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1769:28: note: in expansion of macro 'PTR2nat'
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^~~~~~~
..\toke.c:4463:26: note: in expansion of macro 'FPTR2DPTR'
if (IoANY(datasv) == FPTR2DPTR(void *, funcp)) {
^~~~~~~~~
..\perl.h:1769:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^
..\toke.c:4463:26: note: in expansion of macro 'FPTR2DPTR'
if (IoANY(datasv) == FPTR2DPTR(void *, funcp)) {
^~~~~~~~~
..\toke.c: In function 'Perl_filter_read':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1768:28: note: in expansion of macro 'PTR2nat'
#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
^~~~~~~
..\toke.c:4554:13: note: in expansion of macro 'DPTR2FPTR'
funcp = DPTR2FPTR(filter_t, IoANY(datasv));
^~~~~~~~~
..\perl.h:1768:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
^
..\toke.c:4554:13: note: in expansion of macro 'DPTR2FPTR'
funcp = DPTR2FPTR(filter_t, IoANY(datasv));
^~~~~~~~~
In file included from ..\perl.h:5644:0,
from ..\toke.c:40:
..\toke.c: In function 'S_pending_ident':
..\perl.h:1734:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
# define INT2PTR(any,d) (any)(d)
^
..\embed.h:427:59: note: in definition of macro 'newUNOP_AUX'
#define newUNOP_AUX(a,b,c,d) Perl_newUNOP_AUX(aTHX_ a,b,c,d)
^
..\toke.c:8912:37: note: in expansion of macro 'INT2PTR'
INT2PTR(UNOP_AUX_item *,
^~~~~~~
I get a bunch of warnings beforehand about casting from pointers to integers of different sizes, but this is the bit where it stops and produces an error. Am I missing something obvious? I haven't done this for a while, so I'm hoping it is a silly user error on my part! Thanks.
Try obtaining the MinGW source packages, and installing using makepkg-mingw to build them.
Most if not all have patches applied to customize (or fix) them for the MSYS2/MinGW environment.
Stock source downloaded from its author may not compile directly in that environment the way it would on Linux, or OS X using "configure" and "make".
Instructions are available, and there may be other similar instructions out there associated with Arch Linux.

clang-tidy 4.0 clang-analyzer-alpha.unix.PthreadLock check

Even after I thought that this check was missing, I am now suddenly getting the output of clang-analyzer-alpha.unix.PthreadLock check from the clang-tidy 4.0 tool. Here is a toned down use case of my code which I am trying to modernize by using clang-tidy tool.
I have enabled all the checks using -checks=* argument.
#include <boost/thread.hpp>
#include <boost/thread/once.hpp>
void foo2()
{
boost:mutex mymutex;
boost::mutex::scoped_lock lock(mymutex);
int* x = NULL; // This is intentional. This triggers the clang-tidy checks. If I remove this lines, I wont get the clang-tidy warnings/errors/recommendations.
}
int main() {
foo2();
return 0;
}
When clang-tidy is ran over this code,it produces following warnings.
path/boost/include/boost/thread/pthread/mutex.hpp:149:23: warning: This lock has already been acquired [clang-analyzer-alpha.unix.PthreadLock]
int res = posix::pthread_mutex_lock(&m);
^
path/Source.cpp:40:5: note: Calling 'foo2'
foo2();
^
path/Source.cpp:32:31: note: Calling constructor for 'unique_lock'
boost::mutex::scoped_lock lock(getMutex());
^
path/boost/include/boost/thread/lock_types.hpp:157:7: note: Calling 'unique_lock::lock'
lock();
^
path/boost/include/boost/thread/lock_types.hpp:369:7: note: Taking false branch
if (m == 0)
^
path/boost/include/boost/thread/lock_types.hpp:374:7: note: Taking false branch
if (owns_lock())
^
path/boost/include/boost/thread/lock_types.hpp:379:7: note: Calling 'mutex::lock'
m->lock();
^
path/boost/thread/pthread/mutex.hpp:149:23: note: This lock has already been acquired
int res = posix::pthread_mutex_lock(&m);
^
path/Source.cpp:34:10: warning: unused variable 'x' [clang-diagnostic-unused-variable]
int* x = NULL;
^
path/Source.cpp:34:14: warning: use nullptr [modernize-use-nullptr]
int* x = NULL;
^
nullptr
Suppressed 33125 warnings (33125 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
Why does clang-tidy think that this lock has already been taken? Two functions are totally apart and the lock inside foo2 has no relation to lock in the boost headers. Is this an incorrect warning ? If not then what should I do about it?

Why does __VA_ARGS__ variable macro expansion blows up with GCC 5.1 using forward-declared std::string?

In file included from ./../folly/FBString.h:59:0,
from ./../folly/Conv.h:27,
from detail/CacheLocality.cpp:23:
./../folly/Traits.h:155:38: error: template argument 1 is invalid
struct IsRelocatable< __VA_ARGS__ > : std::true_type {};
^
./../folly/Traits.h:221:3: note: in expansion of macro 'FOLLY_ASSUME_RELOCATABLE'
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2, T3>) } \
^
./../folly/Traits.h:427:1: note: in expansion of macro 'FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3'
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string);
^
./../folly/Traits.h:171:48: error: template argument 1 is invalid
struct has_nothrow_constructor< __VA_ARGS__ > : ::boost::true_type {};
^
./../folly/Traits.h:224:5: note: in expansion of macro 'FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR'
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__<T1, T2, T3>) }
^
./../folly/Traits.h:427:1: note: in expansion of macro 'FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3'
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string);
^
./../folly/Traits.h:155:38: error: template argument 1 is invalid
struct IsRelocatable< __VA_ARGS__ > : std::true_type {};
^
./../folly/Traits.h:213:3: note: in expansion of macro 'FOLLY_ASSUME_RELOCATABLE'
FOLLY_ASSUME_RELOCATABLE(__VA_ARGS__<T1, T2>) } \
^
./../folly/Traits.h:429:1: note: in expansion of macro 'FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2'
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::list);
^
./../folly/Traits.h:171:48: error: template argument 1 is invalid
struct has_nothrow_constructor< __VA_ARGS__ > : ::boost::true_type {};
^
./../folly/Traits.h:216:5: note: in expansion of macro 'FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR'
FOLLY_ASSUME_HAS_NOTHROW_CONSTRUCTOR(__VA_ARGS__<T1, T2>) }
^
./../folly/Traits.h:429:1: note: in expansion of macro 'FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2'
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::list);
^
Makefile:1395: recipe for target 'detail/CacheLocality.lo' failed
To me this looks fine, yet the compiler complains.
So the code above is simple enough. For reference folly is open source code that one can lookup, it's here:
https://github.com/xnox/folly/commit/ca2e9c7f1b6bf92f1f67ae627692547710932577
The core problem was that gcc claimed that "std::string" is ambigious...
However that sounds crazy right... well the code did a forward declaration of std::string, but dual-abi 98/11 libstdc++ diverts std::string to std::__cxx11::string via inline namespacing. Hence gcc started to see std::string as ambigious after the "non-inline namespace forward declare from userspace". Clearly this is broken behaviour and one shall not forward declare std::string, or any std::* stuff for that matter.

gcc: -Dvar=value not working as expected

I am trying to compile a library that has these lines:
#if AE_OS==AE_WINDOWS
#include windows.h
//stuff
#elif AE_OS==AE_POSIX
//other stuff
#endif
When I use cpp -DAE_OS=AE_POSIX I get
cpp/src/ap.cpp:63:21: fatal error: windows.h: No such file or directory
#include <windows.h>
^
Adding a space after the -D does not work, nor does putting AE_OS=AE_POSIX in single or double quotes, putting only AE_POSIX in single or double quotes, and trying all of these combinations with the quotes escaped.
Putting AE_POSIX in escaped single quotes at least does something different, but it is apparently still not correct:
cpp/src/ap.cpp:59:5: warning: character constant too long for its type [enabled by default]
#if AE_OS==AE_WINDOWS
^
I have also tried -D"AE_OS AE_POSIX" thinking that would be the same as #define "AE_OS AE_POSIX" but apparently it ignores the quotes since it defines AE_OS as 1:
<command-line>:0:16: error: missing binary operator before token "1"
cpp/src/ap.cpp:65:7: note: in expansion of macro ‘AE_OS’
#elif AE_OS==AE_POSIX
What is the correct way to do this?
The preprocessor understands expressions of integer type, not strings.
AE_POSIX and AE_WINDOWS are defined as different integers:
/*
* definitions
*/
#define AE_UNKNOWN 0
#define AE_MSVC 1
#define AE_GNUC 2
#define AE_SUNC 3
#define AE_INTEL 1
#define AE_SPARC 2
#define AE_WINDOWS 1
#define AE_POSIX 2
So for POSIX do this:
cpp -DAE_OS=2

Resources