Skip to content

[SYCLomatic][intercept-build] Refine libear's implementation to fix the failure of 4 lit tests related to intercept-build tool in corner case #2730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 16, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 34 additions & 72 deletions clang/tools/scan-build-py/lib/libear/ear.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,28 +487,40 @@ static int call_eaccess(const char *pathname, int mode) {
return result;
}

int eaccess(const char *pathname, int mode) {
int ret = call_eaccess(pathname, mode);
if (ret == 0) {
return 0;
}
int is_nvcc_available(void) {
char *compiler = getenv("INTERCEPT_COMPILE_PATH");
char *is_compiler_exported =
getenv("IS_INTERCEPT_COMPILE_PATH_FROM_ENV_PATH");

int nvcc_available = 0;
char *value = getenv("INTERCEPT_COMPILE_PATH");
if (value) {
nvcc_available = 1;
// Consider tool chain is avaialbe only when it is available from env path.
if (is_compiler_exported && *is_compiler_exported == '1' && compiler) {
return 1;
}
return 0;
}

int is_nvcc_cmd(const char *pathname) {
int len = strlen(pathname);
if (!nvcc_available && len == 4 && pathname[3] == 'c' && pathname[2] == 'c' &&
if (len == 4 && pathname[3] == 'c' && pathname[2] == 'c' &&
pathname[1] == 'v' && pathname[0] == 'n') {
// To handle case like "nvcc foo.cu ..."
return 0;
return 1;
}
if (!nvcc_available && len > 4 && pathname[len - 1] == 'c' &&
pathname[len - 2] == 'c' && pathname[len - 3] == 'v' &&
pathname[len - 4] == 'n' && pathname[len - 5] == '/') {
if (len > 4 && pathname[len - 1] == 'c' && pathname[len - 2] == 'c' &&
pathname[len - 3] == 'v' && pathname[len - 4] == 'n' &&
pathname[len - 5] == '/') {
// To handle case like "/path/to/nvcc foo.cu ..."
return 1;
}
return 0;
}

int eaccess(const char *pathname, int mode) {
int ret = call_eaccess(pathname, mode);
if (ret == 0) {
return 0;
}
if (!is_nvcc_available() && is_nvcc_cmd(pathname)) {
return 0;
}
return ret;
Expand Down Expand Up @@ -538,35 +550,8 @@ int stat(const char *pathname, struct stat *statbuf) {
if (ret == 0) {
return 0;
}
int len = strlen(pathname);
if (len == 4 && pathname[3] == 'c' && pathname[2] == 'c' &&
pathname[1] == 'v' && pathname[0] == 'n') {
// To handle case like "nvcc foo.cu ..."

const char *nvcc_path = getenv("INTERCEPT_COMPILE_PATH");
if (nvcc_path) {
call_stat(nvcc_path, statbuf);
return 0;
}

pathname = get_intercept_stub_path();
call_stat(pathname, statbuf);
return 0;
}

if (len > 4 && pathname[len - 1] == 'c' && pathname[len - 2] == 'c' &&
pathname[len - 3] == 'v' && pathname[len - 4] == 'n' &&
pathname[len - 5] == '/') {
// To handle case like "/path/to/nvcc foo.cu ..."

const char *nvcc_path = getenv("INTERCEPT_COMPILE_PATH");
if (nvcc_path) {
call_stat(nvcc_path, statbuf);
return 0;
}

pathname = get_intercept_stub_path();
call_stat(pathname, statbuf);
if (!is_nvcc_available() && is_nvcc_cmd(pathname)) {
return 0;
}
return ret;
Expand Down Expand Up @@ -1724,33 +1709,10 @@ char *replace_binary_name(const char *src, const char *pos, int compiler_idx,
int is_tool_available(char const *argv[], size_t const argc) {
const char *pathname = argv[0];
int len = strlen(pathname);
int is_nvcc = 0;
int is_nvcc_available = 0;

char *value = getenv("INTERCEPT_COMPILE_PATH");
if (value) {
is_nvcc_available = 1;
}

if (len == 4 && pathname[3] == 'c' && pathname[2] == 'c' &&
pathname[1] == 'v' && pathname[0] == 'n') {
// To handle case like "nvcc"
is_nvcc = 1;
value = getenv("IS_INTERCEPT_COMPILE_PATH_FROM_ENV_PATH");
if (value && *value == '0') {
return 0;
}
}
if (len > 4 && pathname[len - 1] == 'c' && pathname[len - 2] == 'c' &&
pathname[len - 3] == 'v' && pathname[len - 4] == 'n' &&
pathname[len - 5] == '/') {
// To handle case like "/path/to/nvcc"
is_nvcc = 1;
}
if (is_nvcc) {
if (is_nvcc_available) {
if (is_nvcc_cmd(pathname)) {
if (is_nvcc_available())
return 1;
}
return 0;
}

Expand All @@ -1765,7 +1727,7 @@ int is_tool_available(char const *argv[], size_t const argc) {
is_ld = 1;
}
if (is_ld) {
if (!is_nvcc_available) {
if (!is_nvcc_available()) {
for (size_t idx = 0; idx < argc; idx++) {
// if ld linker command uses cuda libarary like libcuda.so or
// libcudart.so, then the ld command should be intercepted.
Expand All @@ -1776,12 +1738,12 @@ int is_tool_available(char const *argv[], size_t const argc) {
}
}

if (!is_nvcc_available && argc == 3) {
if (!is_nvcc_available() && argc == 3) {
// To handle case like "/bin/[sh/bash] -c '[echo or something]
// [/path/to/]nvcc -c foo.cu -o foo.o'" on the environment where tool chain
// is not available.
int is_bash = 0;
is_nvcc = 0;
int is_nvcc_cmd = 0;
const char *pathname = argv[0];
len = strlen(pathname);

Expand All @@ -1805,7 +1767,7 @@ int is_tool_available(char const *argv[], size_t const argc) {
}

if (pos) {
is_nvcc =
is_nvcc_cmd =
pos > argv[2]
? strlen(pos) >= 4 && isspace(*(pos + 4)) &&
(*(pos - 1) == '/' || *(pos - 1) == ';' ||
Expand All @@ -1816,7 +1778,7 @@ int is_tool_available(char const *argv[], size_t const argc) {
// sure it is a compiler command.
}

if (is_bash && strcmp(argv[1], "-c") == 0 && is_nvcc) {
if (is_bash && strcmp(argv[1], "-c") == 0 && is_nvcc_cmd) {
return 0;
}
}
Expand Down