Skip to content

Commit 1bbbfa0

Browse files
committed
cswrap-core: skip known wrappers while invoking an analyzer
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: #43 Closes: #44
1 parent 983b895 commit 1bbbfa0

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

src/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ macro(add_cs_executable name sources)
8888
string(REGEX REPLACE "\\+\\+$" "" name_upper ${name_upper})
8989

9090
if(PATH_TO_${name_upper})
91-
target_compile_definitions(${name}
92-
PRIVATE -DPATH_TO_${name_upper}=${PATH_TO_${name_upper}})
91+
set(def -DPATH_TO_${name_upper}=${PATH_TO_${name_upper}})
92+
target_compile_definitions(cswrap PRIVATE ${def})
93+
target_compile_definitions(${name} PRIVATE ${def})
9394
endif()
9495

9596
install(TARGETS ${name} DESTINATION ${CMAKE_INSTALL_BINDIR})

src/cswrap-core.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,61 @@ static bool read_custom_opts(char **dst, const char *str)
366366
}
367367
}
368368

369+
#if defined(PATH_TO_CSCLNG) || defined(PATH_TO_CSGCCA) \
370+
|| defined(PATH_TO_CSMATCH) || defined(PATH_TO_CSCPPC)
371+
/* if `path` starts with `prefix`, remove the prefix and the trailing ':' */
372+
static bool remove_path_prefix(char *path, const char *prefix)
373+
{
374+
const size_t prefix_len = strlen(prefix);
375+
if (strncmp(path, prefix, prefix_len))
376+
// prefix not found
377+
return false;
378+
379+
// skip all ':' that follow the prefix
380+
const char *end = path + prefix_len;
381+
while (*end == ':')
382+
++end;
383+
384+
// remove the prefix, including the trailing double dots
385+
const size_t new_size = strlen(end) + /* NUL */ 1;
386+
memmove(path, end, new_size);
387+
return true;
388+
}
389+
390+
/* if `path` starts with path to a known wrapper, remove the prefix */
391+
static bool remove_known_wrapper_from_path(char *path)
392+
{
393+
bool removed = false;
394+
#ifdef PATH_TO_CSCLNG
395+
removed |= remove_path_prefix(path, PATH_TO_CSCLNG);
396+
#endif
397+
#ifdef PATH_TO_CSGCCA
398+
removed |= remove_path_prefix(path, PATH_TO_CSGCCA);
399+
#endif
400+
#ifdef PATH_TO_CSMATCH
401+
removed |= remove_path_prefix(path, PATH_TO_CSMATCH);
402+
#endif
403+
#ifdef PATH_TO_CSCPPC
404+
removed |= remove_path_prefix(path, PATH_TO_CSCPPC);
405+
#endif
406+
return removed;
407+
}
408+
409+
/* remove paths to known wrappers from the beginning of $PATH */
410+
static void sanitize_path_for_analyzer(void)
411+
{
412+
char *path = getenv("PATH");
413+
if (!path || !*path)
414+
return;
415+
416+
/* the `path` string will be modified in place */
417+
while (remove_known_wrapper_from_path(path))
418+
;
419+
}
420+
#else
421+
# define sanitize_path_for_analyzer()
422+
#endif
423+
369424
static void consider_running_analyzer(
370425
const int argc_orig,
371426
char **const argv_orig)
@@ -437,6 +492,7 @@ static void consider_running_analyzer(
437492
}
438493

439494
/* try to start analyzer */
495+
sanitize_path_for_analyzer();
440496
pid_analyzer = launch_tool(analyzer_name_actual, argv, /* del_args */ NULL);
441497

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

0 commit comments

Comments
 (0)