GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 87.7% 221 / 3 / 255
Functions: 81.5% 22 / 0 / 27
Branches: 48.1% 306 / 8 / 644

src/driver/Driver.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "Driver.h"
4
5 #include <exception/CliError.h>
6 #include <util/CommonUtil.h>
7 #include <util/CompilerWarning.h>
8 #include <util/SystemUtil.h>
9
10 #include <llvm/Support/CommandLine.h>
11 #include <llvm/TargetParser/Host.h>
12 #include <llvm/TargetParser/Triple.h>
13
14 namespace spice::compiler {
15
16
3/6
✓ Branch 4 → 5 taken 462 times.
✗ Branch 4 → 51 not taken.
✓ Branch 7 → 8 taken 462 times.
✗ Branch 7 → 45 not taken.
✓ Branch 8 → 9 taken 462 times.
✗ Branch 8 → 43 not taken.
1848 Driver::Driver(CliOptions &foreignCliOptions, bool dryRun) : cliOptions(foreignCliOptions), performDryRun(dryRun) {
17 // Allow positional args
18 462 app.positionals_at_end();
19 462 app.allow_extras(false);
20
2/4
✓ Branch 15 → 16 taken 462 times.
✗ Branch 15 → 57 not taken.
✓ Branch 17 → 18 taken 462 times.
✗ Branch 17 → 55 not taken.
462 app.footer("(c) Marc Auberer 2021-" + std::to_string(CommonUtil::getCurrentYear()));
21
22 // Add version flag
23
4/8
✓ Branch 23 → 24 taken 462 times.
✗ Branch 23 → 70 not taken.
✓ Branch 24 → 25 taken 462 times.
✗ Branch 24 → 67 not taken.
✓ Branch 27 → 28 taken 462 times.
✗ Branch 27 → 61 not taken.
✓ Branch 28 → 29 taken 462 times.
✗ Branch 28 → 59 not taken.
1848 app.set_version_flag("--version,-v", CommonUtil::buildVersionInfo());
24
25 // Create sub-commands
26
1/2
✓ Branch 34 → 35 taken 462 times.
✗ Branch 34 → 74 not taken.
462 addBuildSubcommand();
27
1/2
✓ Branch 35 → 36 taken 462 times.
✗ Branch 35 → 74 not taken.
462 addRunSubcommand();
28
1/2
✓ Branch 36 → 37 taken 462 times.
✗ Branch 36 → 74 not taken.
462 addTestSubcommand();
29
1/2
✓ Branch 37 → 38 taken 462 times.
✗ Branch 37 → 74 not taken.
462 addInstallSubcommand();
30
1/2
✓ Branch 38 → 39 taken 462 times.
✗ Branch 38 → 74 not taken.
462 addUninstallSubcommand();
31
32 462 app.final_callback([&] {
33 // Print help text for the root command if no sub-command was given
34
2/4
✓ Branch 2 → 3 taken 458 times.
✗ Branch 2 → 124 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 15 taken 458 times.
458 if (app.get_subcommands().empty()) {
35 std::cout << app.help();
36 return;
37 }
38
39
4/4
✓ Branch 15 → 16 taken 457 times.
✓ Branch 15 → 17 taken 1 time.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 16 → 52 taken 456 times.
458 if (shouldInstall || shouldUninstall) {
40 // Prepare the installation path
41
1/2
✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 152 not taken.
2 std::filesystem::path installPath = SystemUtil::getSpiceBinDir();
42
2/4
✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 136 not taken.
✓ Branch 19 → 20 taken 2 times.
✗ Branch 19 → 134 not taken.
2 installPath /= cliOptions.mainSourceFile.stem();
43
1/2
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 2 times.
2 if (!performDryRun)
44 create_directories(installPath);
45
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 2 times.
2 assert(cliOptions.outputContainer == OutputContainer::EXECUTABLE);
46
3/6
✓ Branch 25 → 26 taken 2 times.
✗ Branch 25 → 139 not taken.
✓ Branch 26 → 27 taken 2 times.
✗ Branch 26 → 139 not taken.
✓ Branch 27 → 28 taken 2 times.
✗ Branch 27 → 137 not taken.
2 installPath.replace_extension(SystemUtil::getOutputFileExtension(cliOptions, OutputContainer::EXECUTABLE));
47
48 // If the binary should be installed, set the output path to the Spice bin directory
49
2/2
✓ Branch 29 → 30 taken 1 time.
✓ Branch 29 → 31 taken 1 time.
2 if (shouldInstall)
50
1/2
✓ Branch 30 → 31 taken 1 time.
✗ Branch 30 → 150 not taken.
1 cliOptions.outputPath = installPath;
51
52 // If the binary should be uninstalled, check if the executable exists and uninstall it
53
3/4
✓ Branch 31 → 32 taken 1 time.
✓ Branch 31 → 50 taken 1 time.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 50 taken 1 time.
2 if (shouldUninstall && !performDryRun) {
54 if (exists(installPath) && std::filesystem::remove(installPath))
55 std::cout << "Successfully uninstalled.\n";
56 else
57 CompilerWarning(UNINSTALL_FAILED, "The executable was not found at the expected location").print();
58 }
59 2 }
60
61 // Abort here if we do not need to compile
62
2/2
✓ Branch 52 → 53 taken 1 time.
✓ Branch 52 → 54 taken 457 times.
458 if (!shouldCompile)
63 1 return;
64
65 // Set output path and dir
66
2/2
✓ Branch 54 → 55 taken 4 times.
✓ Branch 54 → 82 taken 453 times.
457 if (shouldExecute) {
67 4 cliOptions.execute = true;
68
1/2
✓ Branch 57 → 58 taken 4 times.
✗ Branch 57 → 153 not taken.
4 const long millis = duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
69
8/16
✓ Branch 59 → 60 taken 4 times.
✗ Branch 59 → 175 not taken.
✓ Branch 60 → 61 taken 4 times.
✗ Branch 60 → 173 not taken.
✓ Branch 61 → 62 taken 4 times.
✗ Branch 61 → 169 not taken.
✓ Branch 62 → 63 taken 4 times.
✗ Branch 62 → 165 not taken.
✓ Branch 63 → 64 taken 4 times.
✗ Branch 63 → 162 not taken.
✓ Branch 64 → 65 taken 4 times.
✗ Branch 64 → 160 not taken.
✓ Branch 65 → 66 taken 4 times.
✗ Branch 65 → 158 not taken.
✓ Branch 66 → 67 taken 4 times.
✗ Branch 66 → 156 not taken.
4 cliOptions.outputDir = std::filesystem::temp_directory_path() / "spice" / "output" / std::to_string(millis);
70
2/4
✓ Branch 76 → 77 taken 4 times.
✗ Branch 76 → 180 not taken.
✓ Branch 77 → 78 taken 4 times.
✗ Branch 77 → 178 not taken.
4 cliOptions.outputPath = cliOptions.outputDir / cliOptions.mainSourceFile.filename();
71
2/2
✓ Branch 83 → 84 taken 1 time.
✓ Branch 83 → 99 taken 452 times.
453 } else if (!cliOptions.outputPath.empty()) {
72
1/2
✗ Branch 85 → 86 not taken.
✓ Branch 85 → 93 taken 1 time.
1 if (is_directory(cliOptions.outputPath)) {
73 cliOptions.outputDir = cliOptions.outputPath;
74 cliOptions.outputPath = cliOptions.outputDir / cliOptions.mainSourceFile.filename();
75
1/2
✓ Branch 94 → 95 taken 1 time.
✗ Branch 94 → 106 not taken.
1 } else if (cliOptions.outputPath.has_parent_path()) {
76
1/2
✓ Branch 95 → 96 taken 1 time.
✗ Branch 95 → 186 not taken.
1 cliOptions.outputDir = cliOptions.outputPath.parent_path();
77 }
78 } else {
79 452 cliOptions.outputDir = "./";
80
2/4
✓ Branch 100 → 101 taken 452 times.
✗ Branch 100 → 189 not taken.
✓ Branch 101 → 102 taken 452 times.
✗ Branch 101 → 187 not taken.
452 cliOptions.outputPath = cliOptions.outputDir / cliOptions.mainSourceFile.filename();
81 }
82
83 // Set output file extension
84
3/6
✓ Branch 106 → 107 taken 457 times.
✗ Branch 106 → 193 not taken.
✓ Branch 107 → 108 taken 457 times.
✗ Branch 107 → 193 not taken.
✓ Branch 108 → 109 taken 457 times.
✗ Branch 108 → 191 not taken.
457 cliOptions.outputPath.replace_extension(SystemUtil::getOutputFileExtension(cliOptions, cliOptions.outputContainer));
85
86 // Set cache dir
87
5/10
✓ Branch 110 → 111 taken 457 times.
✗ Branch 110 → 206 not taken.
✓ Branch 111 → 112 taken 457 times.
✗ Branch 111 → 202 not taken.
✓ Branch 112 → 113 taken 457 times.
✗ Branch 112 → 199 not taken.
✓ Branch 113 → 114 taken 457 times.
✗ Branch 113 → 197 not taken.
✓ Branch 114 → 115 taken 457 times.
✗ Branch 114 → 195 not taken.
457 cliOptions.cacheDir = std::filesystem::temp_directory_path() / "spice" / "cache";
88
89 // Create directories in case they not exist yet
90 457 create_directories(cliOptions.cacheDir);
91 457 create_directories(cliOptions.outputDir);
92 });
93 462 }
94
95 /**
96 * Start the parsing process
97 *
98 * @param argc Argument count
99 * @param argv Argument vector
100 * @return Return code
101 */
102 462 int Driver::parse(int argc, const char *argv[]) {
103 try {
104
2/2
✓ Branch 2 → 3 taken 458 times.
✓ Branch 2 → 5 taken 1 time.
462 app.parse(argc, argv);
105 458 return EXIT_SUCCESS;
106
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
1 } catch (const CLI::ParseError &parseError) {
107
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 11 not taken.
1 return app.exit(parseError);
108 1 }
109 }
110
111 /**
112 * Initialize the cli options based on the input of the user
113 */
114 459 void Driver::enrich() const {
115 // Make path of given main source file canonical and relative
116
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 9 taken 459 times.
459 if (!performDryRun)
117 cliOptions.mainSourceFile = relative(cliOptions.mainSourceFile);
118
119 // Propagate llvm args to llvm
120
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 31 taken 459 times.
459 if (!cliOptions.llvmArgs.empty()) {
121 const std::vector<std::string> result = CommonUtil::split("llvm " + cliOptions.llvmArgs);
122 std::vector<const char *> resultCStr;
123 resultCStr.reserve(result.size());
124 for (const std::string &str : result)
125 resultCStr.push_back(str.c_str());
126 llvm::cl::ParseCommandLineOptions(static_cast<int>(result.size()), resultCStr.data());
127 }
128
129 // Propagate target information
130
3/6
✓ Branch 31 → 32 taken 459 times.
✗ Branch 31 → 123 not taken.
✓ Branch 33 → 34 taken 459 times.
✗ Branch 33 → 121 not taken.
✓ Branch 34 → 35 taken 459 times.
✗ Branch 34 → 119 not taken.
459 const llvm::Triple defaultTriple(llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()));
131
2/2
✓ Branch 38 → 39 taken 454 times.
✓ Branch 38 → 57 taken 5 times.
459 if (cliOptions.targetTriple.empty()) {
132
2/4
✓ Branch 39 → 40 taken 454 times.
✗ Branch 39 → 160 not taken.
✓ Branch 40 → 41 taken 454 times.
✗ Branch 40 → 49 not taken.
454 if (cliOptions.targetArch == TARGET_UNKNOWN) { // We have nothing -> obtain native triplet
133
1/2
✓ Branch 41 → 42 taken 454 times.
✗ Branch 41 → 160 not taken.
454 cliOptions.targetTriple = defaultTriple;
134
2/4
✓ Branch 42 → 43 taken 454 times.
✗ Branch 42 → 126 not taken.
✓ Branch 43 → 44 taken 454 times.
✗ Branch 43 → 126 not taken.
454 cliOptions.targetArch = defaultTriple.getArchName();
135
2/4
✓ Branch 44 → 45 taken 454 times.
✗ Branch 44 → 127 not taken.
✓ Branch 45 → 46 taken 454 times.
✗ Branch 45 → 127 not taken.
454 cliOptions.targetVendor = defaultTriple.getVendorName();
136
2/4
✓ Branch 46 → 47 taken 454 times.
✗ Branch 46 → 128 not taken.
✓ Branch 47 → 48 taken 454 times.
✗ Branch 47 → 128 not taken.
454 cliOptions.targetOs = defaultTriple.getOSName();
137 454 cliOptions.isNativeTarget = true;
138 } else { // We have arch, vendor and os -> obtain triplet
139 cliOptions.targetTriple = llvm::Triple(cliOptions.targetArch, cliOptions.targetVendor, cliOptions.targetOs);
140 cliOptions.isNativeTarget = cliOptions.targetTriple == defaultTriple;
141 }
142 } else { // Obtain arch, vendor and os by the triplet
143
2/4
✓ Branch 57 → 58 taken 5 times.
✗ Branch 57 → 135 not taken.
✓ Branch 58 → 59 taken 5 times.
✗ Branch 58 → 133 not taken.
5 const llvm::Triple triple(cliOptions.targetTriple.normalize());
144
2/4
✓ Branch 60 → 61 taken 5 times.
✗ Branch 60 → 136 not taken.
✓ Branch 61 → 62 taken 5 times.
✗ Branch 61 → 136 not taken.
5 cliOptions.targetArch = triple.getArchName();
145
2/4
✓ Branch 62 → 63 taken 5 times.
✗ Branch 62 → 137 not taken.
✓ Branch 63 → 64 taken 5 times.
✗ Branch 63 → 137 not taken.
5 cliOptions.targetVendor = triple.getVendorName();
146
2/4
✓ Branch 64 → 65 taken 5 times.
✗ Branch 64 → 138 not taken.
✓ Branch 65 → 66 taken 5 times.
✗ Branch 65 → 138 not taken.
5 cliOptions.targetOs = triple.getOSName();
147 5 cliOptions.isNativeTarget = triple == defaultTriple;
148 5 }
149
150 // Always preserve IR value names when dumping IR
151
2/2
✓ Branch 69 → 70 taken 1 time.
✓ Branch 69 → 71 taken 458 times.
459 if (cliOptions.dump.dumpIR)
152 1 cliOptions.namesForIRValues = true;
153
154 // Enable test mode when test mode was selected
155
2/2
✓ Branch 71 → 72 taken 2 times.
✓ Branch 71 → 73 taken 457 times.
459 if (cliOptions.buildMode == BuildMode::TEST) {
156 2 cliOptions.noEntryFct = true;
157 2 cliOptions.generateTestMain = true;
158 }
159
160 459 const Sanitizer sanitizer = cliOptions.instrumentation.sanitizer;
161 // Memory sanitizer is only supported on Linux
162
4/6
✓ Branch 74 → 75 taken 3 times.
✓ Branch 74 → 77 taken 456 times.
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 77 taken 3 times.
✗ Branch 78 → 79 not taken.
✓ Branch 78 → 87 taken 459 times.
459 if (!cliOptions.targetTriple.isOSLinux() && sanitizer == Sanitizer::MEMORY)
163 throw CliError(FEATURE_NOT_SUPPORTED_FOR_TARGET, "Memory sanitizer is only supported for Linux targets");
164 // Some sanitizers need lifetime markers to work properly
165
4/4
✓ Branch 87 → 88 taken 456 times.
✓ Branch 87 → 89 taken 3 times.
✓ Branch 88 → 89 taken 3 times.
✓ Branch 88 → 90 taken 453 times.
459 if (sanitizer == Sanitizer::ADDRESS || sanitizer == Sanitizer::MEMORY)
166 6 cliOptions.useLifetimeMarkers = true;
167 // Type sanitizer needs TBAA metadata to work properly
168
2/2
✓ Branch 90 → 91 taken 2 times.
✓ Branch 90 → 92 taken 457 times.
459 if (sanitizer == Sanitizer::TYPE)
169 2 cliOptions.useTBAAMetadata = true;
170
171 // Prevent incompatible option combinations
172
3/4
✓ Branch 92 → 93 taken 1 time.
✓ Branch 92 → 102 taken 458 times.
✓ Branch 93 → 94 taken 1 time.
✗ Branch 93 → 102 not taken.
459 if (cliOptions.staticLinking && cliOptions.outputContainer == OutputContainer::SHARED_LIBRARY)
173
2/4
✓ Branch 97 → 98 taken 1 time.
✗ Branch 97 → 154 not taken.
✓ Branch 98 → 99 taken 1 time.
✗ Branch 98 → 151 not taken.
3 throw CliError(INCOMPATIBLE_OPTIONS, "Cannot link statically if compiling shared library");
174 459 }
175
176 /**
177 * Executes the built executable
178 */
179 void Driver::runBinary() const {
180 // Print status message
181 if (cliOptions.printDebugOutput)
182 std::cout << "Running executable ...\n\n";
183
184 // Run executable
185 std::filesystem::path executablePath = cliOptions.outputPath;
186 executablePath.make_preferred();
187 const int exitCode = std::system(executablePath.string().c_str()) / 256;
188 if (exitCode != 0)
189 throw CliError(NON_ZERO_EXIT_CODE, "Your Spice executable exited with non-zero exit code " + std::to_string(exitCode));
190 }
191
192 /**
193 * Add build subcommand to cli interface
194 */
195 462 void Driver::addBuildSubcommand() {
196 // Create sub-command itself
197
3/6
✓ Branch 4 → 5 taken 462 times.
✗ Branch 4 → 160 not taken.
✓ Branch 7 → 8 taken 462 times.
✗ Branch 7 → 154 not taken.
✓ Branch 8 → 9 taken 462 times.
✗ Branch 8 → 152 not taken.
1848 CLI::App *subCmd = app.add_subcommand("build", "Builds your Spice program and emits an executable");
198
2/4
✓ Branch 15 → 16 taken 462 times.
✗ Branch 15 → 166 not taken.
✓ Branch 16 → 17 taken 462 times.
✗ Branch 16 → 164 not taken.
924 subCmd->alias("b");
199 462 subCmd->allow_non_standard_option_names();
200 462 subCmd->configurable();
201 462 subCmd->callback([&] {
202 452 shouldCompile = true; // Requires the source file to be compiled
203 452 });
204
205
1/2
✓ Branch 24 → 25 taken 462 times.
✗ Branch 24 → 308 not taken.
462 addCompileSubcommandOptions(subCmd);
206
1/2
✓ Branch 25 → 26 taken 462 times.
✗ Branch 25 → 308 not taken.
462 addInstrumentationOptions(subCmd);
207
208 7 const auto outputContainerCallback = [&](const CLI::results_t &results) {
209
1/2
✓ Branch 3 → 4 taken 7 times.
✗ Branch 3 → 29 not taken.
7 std::string inputString = results.front();
210
1/2
✓ Branch 5 → 6 taken 7 times.
✗ Branch 5 → 27 not taken.
7 std::ranges::transform(inputString, inputString.begin(), tolower);
211
212
3/4
✓ Branch 6 → 7 taken 7 times.
✗ Branch 6 → 27 not taken.
✓ Branch 7 → 8 taken 2 times.
✓ Branch 7 → 9 taken 5 times.
7 if (inputString == OUTPUT_CONTAINER_EXECUTABLE)
213 2 cliOptions.outputContainer = OutputContainer::EXECUTABLE;
214
3/4
✓ Branch 9 → 10 taken 5 times.
✗ Branch 9 → 27 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 4 times.
5 else if (inputString == OUTPUT_CONTAINER_OBJECT_FILE)
215 1 cliOptions.outputContainer = OutputContainer::OBJECT_FILE;
216
3/4
✓ Branch 12 → 13 taken 4 times.
✗ Branch 12 → 27 not taken.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 3 times.
4 else if (inputString == OUTPUT_CONTAINER_STATIC_LIBRARY)
217 1 cliOptions.outputContainer = OutputContainer::STATIC_LIBRARY;
218
3/4
✓ Branch 15 → 16 taken 3 times.
✗ Branch 15 → 27 not taken.
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 1 time.
3 else if (inputString == OUTPUT_CONTAINER_SHARED_LIBRARY)
219 2 cliOptions.outputContainer = OutputContainer::SHARED_LIBRARY;
220 else
221
1/2
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 24 not taken.
1 throw CliError(INVALID_OUTPUT_CONTAINER, inputString);
222
223 6 return true;
224 7 };
225
226 // --output-container
227
3/6
✓ Branch 29 → 30 taken 462 times.
✗ Branch 29 → 181 not taken.
✓ Branch 33 → 34 taken 462 times.
✗ Branch 33 → 172 not taken.
✓ Branch 34 → 35 taken 462 times.
✗ Branch 34 → 170 not taken.
2310 subCmd->add_option("--output-container", outputContainerCallback,
228 "Format of the compilation output container: exec (default), obj, lib, dylib)");
229 // --target-triple
230
3/6
✓ Branch 43 → 44 taken 462 times.
✗ Branch 43 → 196 not taken.
✓ Branch 46 → 47 taken 462 times.
✗ Branch 46 → 190 not taken.
✓ Branch 47 → 48 taken 462 times.
✗ Branch 47 → 188 not taken.
1848 subCmd->add_option<llvm::Triple>("--target,--target-triple,-t", cliOptions.targetTriple,
231 "Target triple for the emitted executable (for cross-compiling)");
232 // --target-arch
233
3/6
✓ Branch 54 → 55 taken 462 times.
✗ Branch 54 → 208 not taken.
✓ Branch 57 → 58 taken 462 times.
✗ Branch 57 → 202 not taken.
✓ Branch 58 → 59 taken 462 times.
✗ Branch 58 → 200 not taken.
1848 subCmd->add_option<std::string>("--target-arch", cliOptions.targetArch,
234 "Target arch for emitted executable (for cross-compiling)");
235 // --target-vendor
236
3/6
✓ Branch 65 → 66 taken 462 times.
✗ Branch 65 → 220 not taken.
✓ Branch 68 → 69 taken 462 times.
✗ Branch 68 → 214 not taken.
✓ Branch 69 → 70 taken 462 times.
✗ Branch 69 → 212 not taken.
1848 subCmd->add_option<std::string>("--target-vendor", cliOptions.targetVendor,
237 "Target vendor for emitted executable (for cross-compiling)");
238 // --target-os
239
3/6
✓ Branch 76 → 77 taken 462 times.
✗ Branch 76 → 232 not taken.
✓ Branch 79 → 80 taken 462 times.
✗ Branch 79 → 226 not taken.
✓ Branch 80 → 81 taken 462 times.
✗ Branch 80 → 224 not taken.
1848 subCmd->add_option<std::string>("--target-os", cliOptions.targetOs, "Target os for emitted executable (for cross-compiling)");
240 // --output
241
3/6
✓ Branch 87 → 88 taken 462 times.
✗ Branch 87 → 244 not taken.
✓ Branch 90 → 91 taken 462 times.
✗ Branch 90 → 238 not taken.
✓ Branch 91 → 92 taken 462 times.
✗ Branch 91 → 236 not taken.
1848 subCmd->add_option<std::filesystem::path>("--output,-o", cliOptions.outputPath, "Set the output file path");
242 // --disable-verifier
243
3/6
✓ Branch 98 → 99 taken 462 times.
✗ Branch 98 → 256 not taken.
✓ Branch 101 → 102 taken 462 times.
✗ Branch 101 → 250 not taken.
✓ Branch 102 → 103 taken 462 times.
✗ Branch 102 → 248 not taken.
1848 subCmd->add_flag<bool>("--disable-verifier", cliOptions.disableVerifier, "Disable LLVM module and function verification");
244 // --no-entry
245
3/6
✓ Branch 109 → 110 taken 462 times.
✗ Branch 109 → 268 not taken.
✓ Branch 112 → 113 taken 462 times.
✗ Branch 112 → 262 not taken.
✓ Branch 113 → 114 taken 462 times.
✗ Branch 113 → 260 not taken.
1848 subCmd->add_flag<bool>("--no-entry", cliOptions.noEntryFct, "Do not generate main function");
246 // --static
247
3/6
✓ Branch 120 → 121 taken 462 times.
✗ Branch 120 → 280 not taken.
✓ Branch 123 → 124 taken 462 times.
✗ Branch 123 → 274 not taken.
✓ Branch 124 → 125 taken 462 times.
✗ Branch 124 → 272 not taken.
1848 subCmd->add_flag<bool>("--static", cliOptions.staticLinking, "Link statically");
248 // --dump-to-files
249
3/6
✓ Branch 131 → 132 taken 462 times.
✗ Branch 131 → 292 not taken.
✓ Branch 134 → 135 taken 462 times.
✗ Branch 134 → 286 not taken.
✓ Branch 135 → 136 taken 462 times.
✗ Branch 135 → 284 not taken.
1848 subCmd->add_flag<bool>("--dump-to-files", cliOptions.dump.dumpToFiles, "Redirect dumps to files instead of printing");
250 // --abort-after-dump
251
3/6
✓ Branch 142 → 143 taken 462 times.
✗ Branch 142 → 304 not taken.
✓ Branch 145 → 146 taken 462 times.
✗ Branch 145 → 298 not taken.
✓ Branch 146 → 147 taken 462 times.
✗ Branch 146 → 296 not taken.
1848 subCmd->add_flag<bool>("--abort-after-dump", cliOptions.dump.abortAfterDump,
252 "Abort the compilation process after dumping the first requested resource");
253 462 }
254
255 /**
256 * Add run subcommand to cli interface
257 */
258 462 void Driver::addRunSubcommand() {
259 // Create sub-command itself
260
3/6
✓ Branch 4 → 5 taken 462 times.
✗ Branch 4 → 45 not taken.
✓ Branch 7 → 8 taken 462 times.
✗ Branch 7 → 39 not taken.
✓ Branch 8 → 9 taken 462 times.
✗ Branch 8 → 37 not taken.
1848 CLI::App *subCmd = app.add_subcommand("run", "Builds your Spice program and runs it immediately");
261
2/4
✓ Branch 15 → 16 taken 462 times.
✗ Branch 15 → 51 not taken.
✓ Branch 16 → 17 taken 462 times.
✗ Branch 16 → 49 not taken.
924 subCmd->alias("r");
262 462 subCmd->allow_non_standard_option_names();
263 462 subCmd->callback([&] {
264 2 shouldCompile = shouldExecute = true; // Requires the source file to be compiled
265 2 });
266
267 462 addCompileSubcommandOptions(subCmd);
268 462 addInstrumentationOptions(subCmd);
269
270 // --disable-verifier
271
3/6
✓ Branch 27 → 28 taken 462 times.
✗ Branch 27 → 63 not taken.
✓ Branch 30 → 31 taken 462 times.
✗ Branch 30 → 57 not taken.
✓ Branch 31 → 32 taken 462 times.
✗ Branch 31 → 55 not taken.
1848 subCmd->add_flag<bool>("--disable-verifier", cliOptions.disableVerifier, "Disable LLVM module and function verification");
272 462 }
273
274 /**
275 * Add test subcommand to cli interface
276 */
277 462 void Driver::addTestSubcommand() {
278 // Create sub-command itself
279
3/6
✓ Branch 4 → 5 taken 462 times.
✗ Branch 4 → 45 not taken.
✓ Branch 7 → 8 taken 462 times.
✗ Branch 7 → 39 not taken.
✓ Branch 8 → 9 taken 462 times.
✗ Branch 8 → 37 not taken.
1848 CLI::App *subCmd = app.add_subcommand("test", "Builds your Spice program and runs all enclosed tests");
280
2/4
✓ Branch 15 → 16 taken 462 times.
✗ Branch 15 → 51 not taken.
✓ Branch 16 → 17 taken 462 times.
✗ Branch 16 → 49 not taken.
924 subCmd->alias("t");
281 462 subCmd->allow_non_standard_option_names();
282 462 subCmd->callback([&] {
283 2 shouldCompile = shouldExecute = true; // Requires the source file to be compiled
284 2 cliOptions.buildMode = BuildMode::TEST; // Set build mode to test
285 2 cliOptions.generateTestMain = true; // An alternative entry function is generated
286 2 cliOptions.noEntryFct = true; // To not have two main functions, disable normal main
287 2 });
288
289 462 addCompileSubcommandOptions(subCmd);
290 462 addInstrumentationOptions(subCmd);
291
292 // --disable-verifier
293
3/6
✓ Branch 27 → 28 taken 462 times.
✗ Branch 27 → 63 not taken.
✓ Branch 30 → 31 taken 462 times.
✗ Branch 30 → 57 not taken.
✓ Branch 31 → 32 taken 462 times.
✗ Branch 31 → 55 not taken.
1848 subCmd->add_flag<bool>("--disable-verifier", cliOptions.disableVerifier, "Disable LLVM module and function verification");
294 462 }
295
296 /**
297 * Add install subcommand to cli interface
298 */
299 462 void Driver::addInstallSubcommand() {
300 // Create sub-command itself
301
3/6
✓ Branch 4 → 5 taken 462 times.
✗ Branch 4 → 33 not taken.
✓ Branch 7 → 8 taken 462 times.
✗ Branch 7 → 27 not taken.
✓ Branch 8 → 9 taken 462 times.
✗ Branch 8 → 25 not taken.
1848 CLI::App *subCmd = app.add_subcommand("install", "Builds your Spice program and installs it to a directory in the PATH");
302
2/4
✓ Branch 15 → 16 taken 462 times.
✗ Branch 15 → 39 not taken.
✓ Branch 16 → 17 taken 462 times.
✗ Branch 16 → 37 not taken.
924 subCmd->alias("i");
303 462 subCmd->allow_non_standard_option_names();
304 462 subCmd->callback([&] {
305 1 shouldCompile = true;
306 1 shouldInstall = true;
307 1 ensureNotDockerized();
308 1 });
309
310 462 addCompileSubcommandOptions(subCmd);
311 462 }
312
313 /**
314 * Add uninstall subcommand to cli interface
315 */
316 462 void Driver::addUninstallSubcommand() {
317 // Create sub-command itself
318
3/6
✓ Branch 4 → 5 taken 462 times.
✗ Branch 4 → 52 not taken.
✓ Branch 7 → 8 taken 462 times.
✗ Branch 7 → 46 not taken.
✓ Branch 8 → 9 taken 462 times.
✗ Branch 8 → 44 not taken.
1848 CLI::App *subCmd = app.add_subcommand("uninstall", "Uninstalls a Spice program from the system");
319
2/4
✓ Branch 15 → 16 taken 462 times.
✗ Branch 15 → 58 not taken.
✓ Branch 16 → 17 taken 462 times.
✗ Branch 16 → 56 not taken.
924 subCmd->alias("u");
320 462 subCmd->allow_non_standard_option_names();
321 462 subCmd->callback([&] {
322 1 shouldUninstall = true;
323 1 ensureNotDockerized();
324 1 });
325
326 // Source file
327
2/4
✓ Branch 25 → 26 taken 462 times.
✗ Branch 25 → 79 not taken.
✓ Branch 28 → 29 taken 462 times.
✗ Branch 28 → 73 not taken.
1386 subCmd->add_option<std::filesystem::path>("<main-source-file>", cliOptions.mainSourceFile, "Main source file")
328
4/8
✓ Branch 29 → 30 taken 462 times.
✗ Branch 29 → 71 not taken.
✓ Branch 32 → 33 taken 462 times.
✗ Branch 32 → 67 not taken.
✓ Branch 33 → 34 taken 462 times.
✗ Branch 33 → 64 not taken.
✓ Branch 34 → 35 taken 462 times.
✗ Branch 34 → 62 not taken.
2310 ->check(CLI::ExistingFile)
329 462 ->required();
330 462 }
331
332 1848 void Driver::addCompileSubcommandOptions(CLI::App *subCmd) const {
333 4 const auto buildModeCallback = [&](const CLI::results_t &results) {
334
1/2
✓ Branch 3 → 4 taken 4 times.
✗ Branch 3 → 26 not taken.
4 std::string inputString = results.front();
335
1/2
✓ Branch 5 → 6 taken 4 times.
✗ Branch 5 → 24 not taken.
4 std::ranges::transform(inputString, inputString.begin(), tolower);
336
337
2/4
✓ Branch 6 → 7 taken 4 times.
✗ Branch 6 → 24 not taken.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 4 times.
4 if (inputString == BUILD_MODE_DEBUG)
338 cliOptions.buildMode = BuildMode::DEBUG;
339
3/4
✓ Branch 9 → 10 taken 4 times.
✗ Branch 9 → 24 not taken.
✓ Branch 10 → 11 taken 3 times.
✓ Branch 10 → 12 taken 1 time.
4 else if (inputString == BUILD_MODE_RELEASE)
340 3 cliOptions.buildMode = BuildMode::RELEASE;
341
2/4
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 24 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 1 time.
1 else if (inputString == BUILD_MODE_TEST)
342 cliOptions.buildMode = BuildMode::TEST;
343 else
344
1/2
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 21 not taken.
1 throw CliError(INVALID_BUILD_MODE, inputString);
345
346 3 return true;
347 4 };
348
349 // --build-mode
350
3/6
✓ Branch 5 → 6 taken 1848 times.
✗ Branch 5 → 304 not taken.
✓ Branch 9 → 10 taken 1848 times.
✗ Branch 9 → 295 not taken.
✓ Branch 10 → 11 taken 1848 times.
✗ Branch 10 → 293 not taken.
9240 subCmd->add_option("--build-mode,-m", buildModeCallback, "Build mode: debug (default), release, test");
351 // --llvm-args
352
3/6
✓ Branch 19 → 20 taken 1848 times.
✗ Branch 19 → 319 not taken.
✓ Branch 22 → 23 taken 1848 times.
✗ Branch 22 → 313 not taken.
✓ Branch 23 → 24 taken 1848 times.
✗ Branch 23 → 311 not taken.
7392 subCmd->add_option<std::string>("--llvm-args,-llvm", cliOptions.llvmArgs, "Additional arguments for LLVM")->join(' ');
353 // --jobs
354
3/6
✓ Branch 31 → 32 taken 1848 times.
✗ Branch 31 → 331 not taken.
✓ Branch 34 → 35 taken 1848 times.
✗ Branch 34 → 325 not taken.
✓ Branch 35 → 36 taken 1848 times.
✗ Branch 35 → 323 not taken.
7392 subCmd->add_option<unsigned short>("--jobs,-j", cliOptions.compileJobCount, "Compile jobs (threads), used for compilation");
355 // --ignore-cache
356
3/6
✓ Branch 42 → 43 taken 1848 times.
✗ Branch 42 → 343 not taken.
✓ Branch 45 → 46 taken 1848 times.
✗ Branch 45 → 337 not taken.
✓ Branch 46 → 47 taken 1848 times.
✗ Branch 46 → 335 not taken.
7392 subCmd->add_flag<bool>("--ignore-cache", cliOptions.ignoreCache, "Force re-compilation of all source files");
357 // --use-lifetime-markers
358
3/6
✓ Branch 53 → 54 taken 1848 times.
✗ Branch 53 → 355 not taken.
✓ Branch 56 → 57 taken 1848 times.
✗ Branch 56 → 349 not taken.
✓ Branch 57 → 58 taken 1848 times.
✗ Branch 57 → 347 not taken.
7392 subCmd->add_flag<bool>("--use-lifetime-markers", cliOptions.useLifetimeMarkers,
359 "Generate lifetime markers to enhance optimizations");
360 // --use-tbaa-metadata
361
3/6
✓ Branch 64 → 65 taken 1848 times.
✗ Branch 64 → 367 not taken.
✓ Branch 67 → 68 taken 1848 times.
✗ Branch 67 → 361 not taken.
✓ Branch 68 → 69 taken 1848 times.
✗ Branch 68 → 359 not taken.
7392 subCmd->add_flag<bool>("--use-tbaa-metadata", cliOptions.useTBAAMetadata,
362 "Generate metadata for type-based alias analysis to enhance optimizations");
363
364 // Opt levels
365
3/6
✓ Branch 75 → 76 taken 1848 times.
✗ Branch 75 → 383 not taken.
✓ Branch 79 → 80 taken 1848 times.
✗ Branch 79 → 373 not taken.
✓ Branch 80 → 81 taken 1848 times.
✗ Branch 80 → 371 not taken.
7392 subCmd->add_flag_callback("-O0", [&] { cliOptions.optLevel = OptLevel::O0; }, "Disable optimization.");
366
3/6
✓ Branch 88 → 89 taken 1848 times.
✗ Branch 88 → 399 not taken.
✓ Branch 92 → 93 taken 1848 times.
✗ Branch 92 → 389 not taken.
✓ Branch 93 → 94 taken 1848 times.
✗ Branch 93 → 387 not taken.
7392 subCmd->add_flag_callback("-O1", [&] { cliOptions.optLevel = OptLevel::O1; }, "Only basic optimization is applied.");
367
3/6
✓ Branch 101 → 102 taken 1848 times.
✗ Branch 101 → 415 not taken.
✓ Branch 105 → 106 taken 1848 times.
✗ Branch 105 → 405 not taken.
✓ Branch 106 → 107 taken 1848 times.
✗ Branch 106 → 403 not taken.
7392 subCmd->add_flag_callback("-O2", [&] { cliOptions.optLevel = OptLevel::O2; }, "More advanced optimization is applied.");
368
3/6
✓ Branch 114 → 115 taken 1848 times.
✗ Branch 114 → 431 not taken.
✓ Branch 118 → 119 taken 1848 times.
✗ Branch 118 → 421 not taken.
✓ Branch 119 → 120 taken 1848 times.
✗ Branch 119 → 419 not taken.
7392 subCmd->add_flag_callback("-O3", [&] { cliOptions.optLevel = OptLevel::O3; }, "Aggressive optimization for best performance.");
369
3/6
✓ Branch 127 → 128 taken 1848 times.
✗ Branch 127 → 447 not taken.
✓ Branch 131 → 132 taken 1848 times.
✗ Branch 131 → 437 not taken.
✓ Branch 132 → 133 taken 1848 times.
✗ Branch 132 → 435 not taken.
7392 subCmd->add_flag_callback("-Os", [&] { cliOptions.optLevel = OptLevel::Os; }, "Size optimization for output executable.");
370
3/6
✓ Branch 140 → 141 taken 1848 times.
✗ Branch 140 → 463 not taken.
✓ Branch 144 → 145 taken 1848 times.
✗ Branch 144 → 453 not taken.
✓ Branch 145 → 146 taken 1848 times.
✗ Branch 145 → 451 not taken.
7392 subCmd->add_flag_callback("-Oz", [&] { cliOptions.optLevel = OptLevel::Oz; }, "Aggressive optimization for best size.");
371
3/6
✓ Branch 153 → 154 taken 1848 times.
✗ Branch 153 → 475 not taken.
✓ Branch 156 → 157 taken 1848 times.
✗ Branch 156 → 469 not taken.
✓ Branch 157 → 158 taken 1848 times.
✗ Branch 157 → 467 not taken.
7392 subCmd->add_flag<bool>("-lto", cliOptions.useLTO, "Enable link time optimization (LTO)");
372
373 // --debug-output
374
3/6
✓ Branch 164 → 165 taken 1848 times.
✗ Branch 164 → 487 not taken.
✓ Branch 167 → 168 taken 1848 times.
✗ Branch 167 → 481 not taken.
✓ Branch 168 → 169 taken 1848 times.
✗ Branch 168 → 479 not taken.
7392 subCmd->add_flag<bool>("--debug-output,-d", cliOptions.printDebugOutput, "Enable debug output");
375 // --dump-cst
376
3/6
✓ Branch 175 → 176 taken 1848 times.
✗ Branch 175 → 499 not taken.
✓ Branch 178 → 179 taken 1848 times.
✗ Branch 178 → 493 not taken.
✓ Branch 179 → 180 taken 1848 times.
✗ Branch 179 → 491 not taken.
7392 subCmd->add_flag<bool>("--dump-cst,-cst", cliOptions.dump.dumpCST, "Dump CST as serialized string and SVG image");
377 // --dump-ast
378
3/6
✓ Branch 186 → 187 taken 1848 times.
✗ Branch 186 → 511 not taken.
✓ Branch 189 → 190 taken 1848 times.
✗ Branch 189 → 505 not taken.
✓ Branch 190 → 191 taken 1848 times.
✗ Branch 190 → 503 not taken.
7392 subCmd->add_flag<bool>("--dump-ast,-ast", cliOptions.dump.dumpAST, "Dump AST as serialized string and SVG image");
379 // --dump-symtab
380
3/6
✓ Branch 197 → 198 taken 1848 times.
✗ Branch 197 → 523 not taken.
✓ Branch 200 → 201 taken 1848 times.
✗ Branch 200 → 517 not taken.
✓ Branch 201 → 202 taken 1848 times.
✗ Branch 201 → 515 not taken.
7392 subCmd->add_flag<bool>("--dump-symtab", cliOptions.dump.dumpSymbolTable, "Dump serialized symbol tables");
381 // --dump-types
382
3/6
✓ Branch 208 → 209 taken 1848 times.
✗ Branch 208 → 535 not taken.
✓ Branch 211 → 212 taken 1848 times.
✗ Branch 211 → 529 not taken.
✓ Branch 212 → 213 taken 1848 times.
✗ Branch 212 → 527 not taken.
7392 subCmd->add_flag<bool>("--dump-types", cliOptions.dump.dumpTypes, "Dump all used types");
383 // --dump-cache-stats
384
3/6
✓ Branch 219 → 220 taken 1848 times.
✗ Branch 219 → 547 not taken.
✓ Branch 222 → 223 taken 1848 times.
✗ Branch 222 → 541 not taken.
✓ Branch 223 → 224 taken 1848 times.
✗ Branch 223 → 539 not taken.
7392 subCmd->add_flag<bool>("--dump-cache-stats", cliOptions.dump.dumpCacheStats, "Dump stats for compiler-internal lookup caches");
385 // --dump-ir
386
3/6
✓ Branch 230 → 231 taken 1848 times.
✗ Branch 230 → 559 not taken.
✓ Branch 233 → 234 taken 1848 times.
✗ Branch 233 → 553 not taken.
✓ Branch 234 → 235 taken 1848 times.
✗ Branch 234 → 551 not taken.
7392 subCmd->add_flag<bool>("--dump-ir,-ir", cliOptions.dump.dumpIR, "Dump LLVM-IR");
387 // --dump-assembly
388
3/6
✓ Branch 241 → 242 taken 1848 times.
✗ Branch 241 → 571 not taken.
✓ Branch 244 → 245 taken 1848 times.
✗ Branch 244 → 565 not taken.
✓ Branch 245 → 246 taken 1848 times.
✗ Branch 245 → 563 not taken.
7392 subCmd->add_flag<bool>("--dump-assembly,-asm,-s", cliOptions.dump.dumpAssembly, "Dump Assembly code");
389 // --dump-object-file
390
3/6
✓ Branch 252 → 253 taken 1848 times.
✗ Branch 252 → 583 not taken.
✓ Branch 255 → 256 taken 1848 times.
✗ Branch 255 → 577 not taken.
✓ Branch 256 → 257 taken 1848 times.
✗ Branch 256 → 575 not taken.
7392 subCmd->add_flag<bool>("--dump-object-file", cliOptions.dump.dumpObjectFiles, "Dump object files");
391 // --dump-dependency-graph
392
3/6
✓ Branch 263 → 264 taken 1848 times.
✗ Branch 263 → 595 not taken.
✓ Branch 266 → 267 taken 1848 times.
✗ Branch 266 → 589 not taken.
✓ Branch 267 → 268 taken 1848 times.
✗ Branch 267 → 587 not taken.
7392 subCmd->add_flag<bool>("--dump-dependency-graph", cliOptions.dump.dumpDependencyGraph, "Dump compile unit dependency graph");
393
394 // Source file
395
2/4
✓ Branch 274 → 275 taken 1848 times.
✗ Branch 274 → 616 not taken.
✓ Branch 277 → 278 taken 1848 times.
✗ Branch 277 → 610 not taken.
5544 subCmd->add_option<std::filesystem::path>("<main-source-file>", cliOptions.mainSourceFile, "Main source file")
396
4/8
✓ Branch 278 → 279 taken 1848 times.
✗ Branch 278 → 608 not taken.
✓ Branch 281 → 282 taken 1848 times.
✗ Branch 281 → 604 not taken.
✓ Branch 282 → 283 taken 1848 times.
✗ Branch 282 → 601 not taken.
✓ Branch 283 → 284 taken 1848 times.
✗ Branch 283 → 599 not taken.
9240 ->check(CLI::ExistingFile)
397 1848 ->required();
398 1848 }
399
400 1386 void Driver::addInstrumentationOptions(CLI::App *subCmd) const {
401 12 const auto sanitizerCallback = [&](const CLI::results_t &results) {
402
1/2
✓ Branch 3 → 4 taken 12 times.
✗ Branch 3 → 32 not taken.
12 std::string inputString = results.front();
403
1/2
✓ Branch 5 → 6 taken 12 times.
✗ Branch 5 → 30 not taken.
12 std::ranges::transform(inputString, inputString.begin(), tolower);
404
405
2/4
✓ Branch 6 → 7 taken 12 times.
✗ Branch 6 → 30 not taken.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 12 times.
12 if (inputString == SANITIZER_NONE)
406 cliOptions.instrumentation.sanitizer = Sanitizer::NONE;
407
3/4
✓ Branch 9 → 10 taken 12 times.
✗ Branch 9 → 30 not taken.
✓ Branch 10 → 11 taken 3 times.
✓ Branch 10 → 12 taken 9 times.
12 else if (inputString == SANITIZER_ADDRESS)
408 3 cliOptions.instrumentation.sanitizer = Sanitizer::ADDRESS;
409
3/4
✓ Branch 12 → 13 taken 9 times.
✗ Branch 12 → 30 not taken.
✓ Branch 13 → 14 taken 3 times.
✓ Branch 13 → 15 taken 6 times.
9 else if (inputString == SANITIZER_THREAD)
410 3 cliOptions.instrumentation.sanitizer = Sanitizer::THREAD;
411
3/4
✓ Branch 15 → 16 taken 6 times.
✗ Branch 15 → 30 not taken.
✓ Branch 16 → 17 taken 3 times.
✓ Branch 16 → 18 taken 3 times.
6 else if (inputString == SANITIZER_MEMORY)
412 3 cliOptions.instrumentation.sanitizer = Sanitizer::MEMORY;
413
3/4
✓ Branch 18 → 19 taken 3 times.
✗ Branch 18 → 30 not taken.
✓ Branch 19 → 20 taken 2 times.
✓ Branch 19 → 21 taken 1 time.
3 else if (inputString == SANITIZER_TYPE)
414 2 cliOptions.instrumentation.sanitizer = Sanitizer::TYPE;
415 else
416
1/2
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 27 not taken.
1 throw CliError(INVALID_SANITIZER, inputString);
417
418 11 return true;
419 12 };
420
421 // --debug-info
422
3/6
✓ Branch 4 → 5 taken 1386 times.
✗ Branch 4 → 37 not taken.
✓ Branch 7 → 8 taken 1386 times.
✗ Branch 7 → 31 not taken.
✓ Branch 8 → 9 taken 1386 times.
✗ Branch 8 → 29 not taken.
5544 subCmd->add_flag<bool>("--debug-info,-g", cliOptions.instrumentation.generateDebugInfo, "Generate debug info");
423 // --sanitizer
424
3/6
✓ Branch 16 → 17 taken 1386 times.
✗ Branch 16 → 52 not taken.
✓ Branch 20 → 21 taken 1386 times.
✗ Branch 20 → 43 not taken.
✓ Branch 21 → 22 taken 1386 times.
✗ Branch 21 → 41 not taken.
6930 subCmd->add_option("--sanitizer", sanitizerCallback, "Enable sanitizer: none (default), address, thread, memory, type");
425 1386 }
426
427 /**
428 * Ensure that the compiler is not running in a Docker container
429 */
430 2 void Driver::ensureNotDockerized() {
431 2 const char *envValue = std::getenv(ENV_VAR_DOCKERIZED);
432 if (envValue != nullptr && std::strcmp(envValue, "true") == 0) { // LCOV_EXCL_START
433 auto errorMsg = "This feature is not supported in a containerized environment. Please use the standalone version of Spice.";
434 throw CliError(FEATURE_NOT_SUPPORTED_WHEN_DOCKERIZED, errorMsg);
435 } // LCOV_EXCL_STOP
436 2 }
437
438 } // namespace spice::compiler
439