0

I have a project that I recently split up into headers + sources, and now clang-tidy wont "actually" check my test files that include these headers. Below is an example of the situation:

File Structure:

src/
  main.c
  a.h
  a.c

test/
  test.c

Code:

// src/main.c
#include "src/a.h"

int main(void) {
    a();

    return 0;
}


// src/a.h
void a(void);


// src/a.c
#include <stdlib.h>
#include "src/a.h"

void a(void) {
    malloc(1); // obvious memory leak
}


// test/test.c
#include "src/a.h"

int main(void) {
    // do test stuff
    a();

    return 0;
}

Compile src: cc src/*.c -I. -o main

Compile test: cc src/a.c test/test.c -I. -o test

Running does nothing, but the code does compile.

Then, I run the code through clang-tidy:

clang-tidy src/* -- -I.

This works:

1 warning generated.
1 warning generated.
1 warning generated.
/src/a.c:8:1: warning: Potential memory leak [clang-analyzer-unix.Malloc]
}
^
/src/a.c:7:2: note: Memory is allocated
        malloc(1);
        ^
/src/a.c:8:1: note: Potential memory leak
}
^

But if I do:

clang-tidy test/test.c -- -I.

Nothing is outputed (ive tried to add the header-filter flag as well).

I pressume that the headers are being included, and the test code has no knowledge of the source. So, how can I make sure my tests are actually being checked if this is the case? These headers and sources are in my project, so it would only make sense that clang-tidy would be able to pick up on this?

Edit:

I can do the following, and it seems to only partially fix the problem:

// test/test.c
#include "src/a.h"
#include "src/a.c" //added this line

int main(void) {
    // do test stuff
    a();

    return 0;
}

Now, clang-tidy picks up on the actual .c file, and thus finds the issue. But, now I cant compile my code. There is supposed to be a __clang_analyzer__ define that gets set when the code is being analyzed, but it seems to just ignore it:

#ifdef __clang_analyzer__
#include "src/a.c" // doesnt include file, thus the malloc() call is never detected
#endif
Dosisod
  • 307
  • 2
  • 15
  • Have you considered that `clang-tidy` simply might not have anything to say about your test sources? In any case, it's not clear to me why you think that headers have any special relevance to the issue. – John Bollinger Jul 22 '20 at 13:49
  • Did you try `clang-tidy test/test.c src/a.c -- -I.` analogous to your build of the test? – the busybee Jul 22 '20 at 13:51
  • @thebusybee I tried that, and it did not seem to fix it. I updated my question with a partial solution, which now causes compilation issues. – Dosisod Jul 25 '20 at 06:18

1 Answers1

1

clang-tidy is only a static analyser tool, said differently a linter. It does not try to build or run an executable: it just analyses the C source files it has been given after processing the include parts.

Static analysis and testing are different parts of a quality assurance process:

  • the former only reads source files searching for common errors and runs nothing
  • the latter runs (parts of) a code base with known inputs and controls that outputs have expected values

That means that clang-tidy is expected to be run on your main sources, not only on the test ones.


To be clear, it can make sense to pass test sources to the linter, because they could contain problems that clang-tidy would detect. But only running clang-tidy on the test folder will not detect problem in main folder, whatever the coverage.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • 2
    Why shouldn't a linter be run on the test sources? They can have errors detectable by static analysis too, and such errors could cause them to operate incorrectly. – John Bollinger Jul 22 '20 at 13:52
  • @JohnBollinger: From your comment, I realize that I was not clear. I did not mean that a programmer should not use a linter on its test sources, I meant that *only running it on the tests sources* would not analyze its main sources. I'll try to make an edit... – Serge Ballesta Jul 22 '20 at 13:58
  • Yes, thank you. And the clarification answers my followup question, too, which was going to be about how this answer responds to the specifics of the question the OP posed. I gather that you're picturing them running the linter on the test sources, and being confused because errors in the main sources are not then reported. I don't know whether that's actually what's happening, but it is plausible. – John Bollinger Jul 22 '20 at 14:05
  • I am running clang-tidy on both my sources and my tests, as the tests are supposed to show how a small snippet of the real code should be used: what things you need to setup to run it, and what must be destroyed after. If clang-tidy is unable to detect these housekeeping related issues in my tests, it puts more of a mental load on me to remember how everything should be cleaned up after im done with it. – Dosisod Jul 23 '20 at 07:26