Skip to content

Commit

Permalink
cswrap-core: skip known wrappers while invoking an analyzer
Browse files Browse the repository at this point in the history
We want to hook `gcc -fanalyzer` on `clang` if `clang` is used as the
system compiler.  However, it does not make sense to hook GCC Analyzer
on `clang --analyze`, which is invoked by `csclng` while wrapping `gcc`
as the system compiler.

Apart from wasting resources by running multiple processes of GCC
Analyzer in parallel, this was causing unnecessary noise in `scan.log`
as GCC Analyzer complained about unsupported flags, which were injected
by `csclng` for `clang --analyze` only:
```
gcc: error: unrecognized command-line option ‘-fno-caret-diagnostics’
gcc: error: unrecognized command-line option ‘-fno-caret-diagnostics’
gcc: error: unrecognized command-line option ‘-fno-caret-diagnostics’
```

Reported-by: Lukáš Zaoral
Fixes: commit 983b895
Related: csutils#43
Closes: csutils#44
  • Loading branch information
kdudka committed Jul 22, 2024
1 parent 983b895 commit 1bbbfa0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ macro(add_cs_executable name sources)
string(REGEX REPLACE "\\+\\+$" "" name_upper ${name_upper})

if(PATH_TO_${name_upper})
target_compile_definitions(${name}
PRIVATE -DPATH_TO_${name_upper}=${PATH_TO_${name_upper}})
set(def -DPATH_TO_${name_upper}=${PATH_TO_${name_upper}})
target_compile_definitions(cswrap PRIVATE ${def})
target_compile_definitions(${name} PRIVATE ${def})
endif()

install(TARGETS ${name} DESTINATION ${CMAKE_INSTALL_BINDIR})
Expand Down
56 changes: 56 additions & 0 deletions src/cswrap-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,61 @@ static bool read_custom_opts(char **dst, const char *str)
}
}

#if defined(PATH_TO_CSCLNG) || defined(PATH_TO_CSGCCA) \
|| defined(PATH_TO_CSMATCH) || defined(PATH_TO_CSCPPC)
/* if `path` starts with `prefix`, remove the prefix and the trailing ':' */
static bool remove_path_prefix(char *path, const char *prefix)
{
const size_t prefix_len = strlen(prefix);
if (strncmp(path, prefix, prefix_len))
// prefix not found
return false;

// skip all ':' that follow the prefix
const char *end = path + prefix_len;
while (*end == ':')
++end;

// remove the prefix, including the trailing double dots
const size_t new_size = strlen(end) + /* NUL */ 1;
memmove(path, end, new_size);
return true;
}

/* if `path` starts with path to a known wrapper, remove the prefix */
static bool remove_known_wrapper_from_path(char *path)
{
bool removed = false;
#ifdef PATH_TO_CSCLNG
removed |= remove_path_prefix(path, PATH_TO_CSCLNG);
#endif
#ifdef PATH_TO_CSGCCA
removed |= remove_path_prefix(path, PATH_TO_CSGCCA);
#endif
#ifdef PATH_TO_CSMATCH
removed |= remove_path_prefix(path, PATH_TO_CSMATCH);
#endif
#ifdef PATH_TO_CSCPPC
removed |= remove_path_prefix(path, PATH_TO_CSCPPC);
#endif
return removed;
}

/* remove paths to known wrappers from the beginning of $PATH */
static void sanitize_path_for_analyzer(void)
{
char *path = getenv("PATH");
if (!path || !*path)
return;

/* the `path` string will be modified in place */
while (remove_known_wrapper_from_path(path))
;
}
#else
# define sanitize_path_for_analyzer()
#endif

static void consider_running_analyzer(
const int argc_orig,
char **const argv_orig)
Expand Down Expand Up @@ -437,6 +492,7 @@ static void consider_running_analyzer(
}

/* try to start analyzer */
sanitize_path_for_analyzer();
pid_analyzer = launch_tool(analyzer_name_actual, argv, /* del_args */ NULL);

/* FIXME: release also the memory allocated by asprintf() and
Expand Down

0 comments on commit 1bbbfa0

Please sign in to comment.