Summary
Automated audit found multiple portability, correctness and maintainability bugs that should be fixed before enabling branch protection / release. Most are triggered on CI (ubuntu-24.04, LLVM 22 apt.llvm.org) or on a fresh clone away from /home/sergio.
1. CMakeLists.txt:23,38 – hardcoded clang-cpp / LLVM search – CI failure 🔴
Location: CMakeLists.txt:23 find_library(CLANG_CPP_LIB clang-cpp HINTS /usr/lib) and :38 find_library(LLVM_SINGLE_LIB LLVM-22 HINTS /usr/lib /usr/lib/llvm)
Evidence:
- CI log:
Found LLVM 22.1.8 at /usr/lib/llvm-22/lib/cmake/llvm → CMake Error at CMakeLists.txt:25 (message): clang-cpp not found
libclang-cpp22-dev on apt.llvm.org/noble installs:
/usr/lib/llvm-22/lib/libclang-cpp.so -> libclang-cpp.so.22.1
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.22.1 (versioned)
/usr/lib/x86_64-linux-gnu/libclang-cpp22.so (dev)
Unversioned libclang-cpp.so only exists at /usr/lib/llvm-22/lib, not in default system search. Similarly libLLVM-22.so lives at /usr/lib/llvm-22/lib/libLLVM-22.so.
- Arch layout (
/usr/lib/libclang-cpp.so, /usr/include) works locally, so bug only visible on CI.
Expected: Support both layouts:
find_library(CLANG_CPP_LIB NAMES clang-cpp clang-cpp-22
HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/llvm-22/lib ${LLVM_LIBRARY_DIRS} ${LLVM_DIR}/../..)
find_path(CLANG_INCLUDE_DIRS NAMES clang/Basic/Version.h
HINTS /usr/include /usr/lib/llvm-22/include ${LLVM_INCLUDE_DIRS})
find_library(LLVM_SINGLE_LIB NAMES LLVM-22 LLVM
HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/llvm-22/lib ${LLVM_LIBRARY_DIRS})
2. src/interpreter/interpreter.cpp:54,57 – hardcoded absolute paths 🔴
compilerArgsStorage_.push_back("/usr/lib/clang/22");
compilerArgsStorage_.push_back("/home/sergio/Project/cpp-repl/include");
/usr/lib/clang/22 is the Arch path. On Ubuntu the resource dir is /usr/lib/llvm-22/lib/clang/22 or discovered via clang::CompilerInstance/llvm-config --prefix. Hardcoding breaks CI and any other install prefix.
/home/sergio/Project/cpp-repl/include makes a fresh git clone elsewhere fail to find cpp-repl/fix_np_headers.hpp (force-included at :59). Repro: clone to /tmp, build – builtin headers break. Should be derived from PROJECT_SOURCE_DIR/CMAKE_CURRENT_SOURCE_DIR or installed prefix, or via target_include_directories.
Same issue in src/repl.cpp:27-28 (legacy Repl):
std::vector<const char *> args = {"-std=c++17", "-O0", "-resource-dir", "/usr/lib/clang/22"};
3. Dead / non-portable Numpy-C-API hints 🔴
src/interpreter/interpreter.cpp:55,548,672,716 contains explanations and error hints referencing a local checkout:
Use -I /home/sergio/Project/Numpy-C-API/include and #include "np/np.hpp"
Try: cpp-repl -std=c++23 -I /home/sergio/Project/Numpy-C-API/include
These paths leak a developer's home dir into user-facing diagnostics and should be generic (/path/to/Numpy-C-API/include or just suggest -I <path>).
4. include/cpp-repl/fix_proxy.hpp:10 – unconditional external include 🔴
#include "np/detail/proxy.hpp"
If this header were ever force-included, it fails unless Numpy-C-API is installed. File is currently dead (only fix_np_headers.hpp is -included) but still presents maintenance risk and breaks clang-tidy/cppcheck if enabled. Either remove or guard with #if __has_include.
5. src/interpreter/interpreter.cpp:266-329 – preprocessBigIntLiterals regex incomplete (functional bug) 🟡
Repro:
./build/cpp-repl --no-interactive -e 'bigint g = 12345678901234567890123456789012345678901234567890;'
# In file included from <<< inputs >>>:1:
# error: integer literal is too large
Expected: auto-wrap to bigint("..."). The regex only handles bigint|cpp_int|... \s+ \w+ \s*=\s* DIGITS ; but fails for:
const bigint, constexpr, static qualifiers before type
- multi-declaration or template types like
const std::vector<cpp_int>, though less common
- The local uncommitted diff already adds handling but still misses
auto literals used as function args, e.g., foo(123456789...)
Should expand to handle qualifiers and report correct type extraction, or better rely on boost::multiprecision::cpp_int's user-defined literal if available.
6. src/repl/session.cpp:20-36 and src/interpreter/interpreter.cpp:824-843 – naive isIncomplete 🟡
Counts {, (, [ without stripping strings/comments. Example:
cpp> std::string s = "{";
...>
incorrectly considered incomplete (open brace in string). Python REPL correctly handles this via tokenization. Should reuse stripCommentsAndStrings logic from VersionDetector or use clang lexing.
7. src/interpreter/interpreter.cpp:233-257,162-179 – reinitWithCurrentOptions/ensureVersion replays history unsafely 🟡
reinitWithCurrentOptions and ensureVersion clear variables_/history_ then replay via eval(h, e) without handling re-entrancy: if replayed code triggers another ensureVersion upgrade, recursion could double-reinit.
variables_ tracking via regex parseDeclaration is lossy (misses std::string, templates, auto, etc.) and can silently corrupt undo state. undo() rebuilds from history but skips failed parseDeclaration, leaving stale entries.
8. src/utils/version_detector.cpp:88-111 – overly broad version detection 🟡
detect checks stripped.find("import") via contains("import ") etc., causing false positives on variable names like int important = 0; → triggers C++23 upgrade. Same for export, format, source_location. Should use containsWord.
9. Hardcoded version string 🟡
src/cli/cli.cpp:126-127 and README.md hardcode LLVM 22.1.3 / clang 22.1.8. CI now uses 22.1.8 for both. Should query LLVM_VERSION_MAJOR/PACKAGE_VERSION at cmake time and embed via configure_file.
10. Build: CMakeLists.txt missing dynamic resource-dir / include handling & HAS_READLINE 🟠
- No
clang -print-resource-dir detection; should use execute_process(clang -print-resource-dir) or ClangConfig.
- Latest
main adds READLINE detection at bottom but interpreter doesn't use it consistently (history handling).
Repro steps
cmake -B build -G Ninja -DLLVM_DIR=/usr/lib/llvm-22/lib/cmake/llvm # CI
# fails at clang-cpp not found before fix
./build/cpp-repl --no-interactive -e 'bigint g = 1234567890123456789012345678901234567890;'
# error: integer literal is too large
git clone elsewhere && cmake -B build && ./build/cpp-repl --no-interactive -e 'int x=1;'
# fails to find fix_np_headers.hpp due to hardcoded /home/sergio path
Suggested priority
Generated by local audit (grep, llvm-config, gh, smoke tests) on e6e94b7 + unstaged changes. Happy to PR the CMake fix above.
Summary
Automated audit found multiple portability, correctness and maintainability bugs that should be fixed before enabling branch protection / release. Most are triggered on CI (
ubuntu-24.04, LLVM 22 apt.llvm.org) or on a fresh clone away from/home/sergio.1.
CMakeLists.txt:23,38– hardcodedclang-cpp/LLVMsearch – CI failure 🔴Location:
CMakeLists.txt:23find_library(CLANG_CPP_LIB clang-cpp HINTS /usr/lib)and:38find_library(LLVM_SINGLE_LIB LLVM-22 HINTS /usr/lib /usr/lib/llvm)Evidence:
Found LLVM 22.1.8 at /usr/lib/llvm-22/lib/cmake/llvm→CMake Error at CMakeLists.txt:25 (message): clang-cpp not foundlibclang-cpp22-devonapt.llvm.org/nobleinstalls:libclang-cpp.soonly exists at/usr/lib/llvm-22/lib, not in default system search. SimilarlylibLLVM-22.solives at/usr/lib/llvm-22/lib/libLLVM-22.so./usr/lib/libclang-cpp.so,/usr/include) works locally, so bug only visible on CI.Expected: Support both layouts:
2.
src/interpreter/interpreter.cpp:54,57– hardcoded absolute paths 🔴/usr/lib/clang/22is the Arch path. On Ubuntu the resource dir is/usr/lib/llvm-22/lib/clang/22or discovered viaclang::CompilerInstance/llvm-config --prefix. Hardcoding breaks CI and any other install prefix./home/sergio/Project/cpp-repl/includemakes a freshgit cloneelsewhere fail to findcpp-repl/fix_np_headers.hpp(force-included at:59). Repro: clone to/tmp, build – builtin headers break. Should be derived fromPROJECT_SOURCE_DIR/CMAKE_CURRENT_SOURCE_DIRor installed prefix, or viatarget_include_directories.Same issue in
src/repl.cpp:27-28(legacyRepl):3. Dead / non-portable Numpy-C-API hints 🔴
src/interpreter/interpreter.cpp:55,548,672,716contains explanations and error hints referencing a local checkout:These paths leak a developer's home dir into user-facing diagnostics and should be generic (
/path/to/Numpy-C-API/includeor just suggest-I <path>).4.
include/cpp-repl/fix_proxy.hpp:10– unconditional external include 🔴If this header were ever force-included, it fails unless Numpy-C-API is installed. File is currently dead (only
fix_np_headers.hppis-included) but still presents maintenance risk and breaksclang-tidy/cppcheckif enabled. Either remove or guard with#if __has_include.5.
src/interpreter/interpreter.cpp:266-329–preprocessBigIntLiteralsregex incomplete (functional bug) 🟡Repro:
Expected: auto-wrap to
bigint("..."). The regex only handlesbigint|cpp_int|... \s+ \w+ \s*=\s* DIGITS ;but fails for:const bigint,constexpr,staticqualifiers before typeconst std::vector<cpp_int>, though less commonautoliterals used as function args, e.g.,foo(123456789...)Should expand to handle qualifiers and report correct
typeextraction, or better rely onboost::multiprecision::cpp_int's user-defined literal if available.6.
src/repl/session.cpp:20-36andsrc/interpreter/interpreter.cpp:824-843– naiveisIncomplete🟡Counts
{,(,[without stripping strings/comments. Example:cpp> std::string s = "{"; ...>incorrectly considered incomplete (open brace in string). Python REPL correctly handles this via tokenization. Should reuse
stripCommentsAndStringslogic fromVersionDetectoror use clang lexing.7.
src/interpreter/interpreter.cpp:233-257,162-179–reinitWithCurrentOptions/ensureVersionreplays history unsafely 🟡reinitWithCurrentOptionsandensureVersionclearvariables_/history_then replay viaeval(h, e)without handling re-entrancy: if replayed code triggers anotherensureVersionupgrade, recursion could double-reinit.variables_tracking via regexparseDeclarationis lossy (missesstd::string, templates,auto, etc.) and can silently corrupt undo state.undo()rebuilds from history but skips failedparseDeclaration, leaving stale entries.8.
src/utils/version_detector.cpp:88-111– overly broad version detection 🟡detectchecksstripped.find("import")viacontains("import ")etc., causing false positives on variable names likeint important = 0;→ triggersC++23upgrade. Same forexport,format,source_location. Should usecontainsWord.9. Hardcoded version string 🟡
src/cli/cli.cpp:126-127andREADME.mdhardcodeLLVM 22.1.3 / clang 22.1.8. CI now uses22.1.8for both. Should queryLLVM_VERSION_MAJOR/PACKAGE_VERSIONat cmake time and embed viaconfigure_file.10. Build:
CMakeLists.txtmissing dynamicresource-dir/ include handling &HAS_READLINE🟠clang -print-resource-dirdetection; should useexecute_process(clang -print-resource-dir)orClangConfig.mainaddsREADLINEdetection at bottom butinterpreterdoesn't use it consistently (history handling).Repro steps
Suggested priority
Generated by local audit (
grep,llvm-config,gh, smoke tests) one6e94b7+ unstaged changes. Happy to PR the CMake fix above.