[EXT_EP-11936] Compiler incorrectly optimizes control flow code in the presence of an empty infinite loop Created: 05/Sep/24 Updated: 20/Mar/25 Resolved: 18/Feb/25 |
|
| Status: | Fixed |
| Project: | Embedded Software & Tools |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Medium |
| Reporter: | TI User | Assignee: | TI User |
| Resolution: | Fixed | Votes: | 0 |
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Product: | Code Generation Tools |
| Internal ID: | CODEGEN-12833 |
| Forum URL: | https://e2e.ti.com/e2eprivate/figure-ai/figure-ai---ep/f/1295/t/1407343 |
| Found In Release: | ARMCLANG_3.2.0.LTS |
| Fix In Release: | ARMCLANG_4.0.2.LTS ARMCLANG_3.2.4.LTS* |
| Affected Platform/Device: | default |
| Workaround: | Workaround #1:
There is an empty while loop at the end of the function that contains the condition statement in question: while (true) ; The 4.0.0.LTS compiler makes the assumption that this is a noreturn function and so the "if (!assert_fired)" condition check is optimized out. To avoid having the "if (!assert_fired)" condition optimized away, insert an asm(" nop\n"); statement inside the while (true) loop at the end of the assertHandler() function in the test case source file. while (true) { asm(" nop\n"); } Workaround #2: A more heavy-handed workaround is to apply an "optnone" attribute to the assertHandler() function like this: __attribute__((optnone)) void Server::assertHandler(etl::string_view description, etl::string_view pretty_function, etl::string_view file, uint32_t line) |
| Description |
|
The attached file has a function that begins ... void Server::assertHandler(etl::string_view description, etl::string_view pretty_function,
etl::string_view file, uint32_t line) {
static bool assert_fired = false;
// Protection from the infinite calling to the handler
// if some of the code bellow triggers the assert.
if (!assert_fired) {
assert_fired = true;
Build it ... % tiarmclang @options.txt file.cpp Ignore the warning and note diagnostics. Create the interlisted, demangled, disassembly with the command ... % tiarmobjdump --demangle --source file.o > disassembly.txt Inspect the disassembly to find the function begins ... 00000000 <figure::lib::logger::Server::assertHandler(etl::basic_string_view<char, etl::char_traits<char>>, etl::basic_string_view<char, etl::char_traits<char>>, etl::basic_string_view<char, etl::char_traits<char>>, unsigned int)>:
; etl::string_view file, uint32_t line) {
0: b08c sub sp, #48
; : mbegin(begin_)
2: f240 0700 movw r7, #0
; assert_fired = true;
The static variable is assert_fired is assigned the value 1 without the conditional check that appears in the C++ source. |