LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 44916 - ftrivial-auto-var-init=pattern doesn't initialize locals in switch statement
Summary: ftrivial-auto-var-init=pattern doesn't initialize locals in switch statement
Status: NEW
Alias: None
Product: clang
Classification: Unclassified
Component: Frontend (show other bugs)
Version: unspecified
Hardware: PC Linux
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-02-14 11:19 PST by Alexander Potapenko
Modified: 2021-02-25 12:46 PST (History)
8 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Potapenko 2020-02-14 11:19:49 PST
In the following case (https://godbolt.org/z/cXxBXz):

#include <stdio.h>
int main(int argc, char **argv) {
  switch (argc) {
    int v;
   case 1:
     v = 2;
   default:
    printf("v(%p): %x\n", &v, v);
  }
  return 0;
}


Clang doesn't force-initialize |v| when run with -ftrivial-auto-var-init=pattern:

$ ./t 2
v(0x7ffcab198224): 7ffc


In the case |v| is moved outside the switch (https://godbolt.org/z/CKPQNz) Clang emits the initialization correctly:

$ ./t 2
v(0x7ffee8020c44): aaaaaaaa
Comment 1 JF Bastien 2020-02-14 14:50:56 PST
FWIW this was a known limitation from the RFC: https://reviews.llvm.org/D54604
IIURC this is a decent amount of work to fix, and I think we'd be better off diagnosing and fixing this type of code.
Comment 2 Alexander Potapenko 2020-02-18 01:33:39 PST
> FWIW this was a known limitation from the RFC: https://reviews.llvm.org/D54604
> IIURC this is a decent amount of work to fix, and I think we'd be better off
> diagnosing and fixing this type of code.

Assignments performed in switch statements are indeed unreachable, and a local variable declared in a switch remains uninitialized.
But aren't we trying to guarantee that uninitialized locals are now initialized? Asking the users to proactively fix their code kind of contradicts with the goal of giving them the flag :)

Also, Linux kernel community will probably oppose to attempts to fix the code in which a local is declared inside a switch statement, but is always initialized before every first use.
Comment 3 Kees Cook 2020-02-19 10:41:58 PST
Note that GCC will actually warn about finding surprise initializers in these cases. Can Clang add that more easily than fixing the situation? (This would get us into the state of "least surprise", in the sense that the condition will warn instead of silently missing initialization.)

fs/fcntl.c: In function ‘send_sigio_to_task’:
fs/fcntl.c:738:13: warning: statement will never be executed [-Wswitch-unreachab
le]
   siginfo_t si;
             ^~
Comment 4 JF Bastien 2020-02-19 10:43:28 PST
(In reply to Kees Cook from comment #3)
> Note that GCC will actually warn about finding surprise initializers in
> these cases. Can Clang add that more easily than fixing the situation? (This
> would get us into the state of "least surprise", in the sense that the
> condition will warn instead of silently missing initialization.)
> 
> fs/fcntl.c: In function ‘send_sigio_to_task’:
> fs/fcntl.c:738:13: warning: statement will never be executed
> [-Wswitch-unreachab
> le]
>    siginfo_t si;
>              ^~

That's the route I would take, but if someone is interested in implementing the completely correct fix (where skipped-over initializations still execute for auto-init) then I'm all for it.
Comment 5 Kees Cook 2021-02-25 11:02:00 PST
Updated godbolt to show uninit, pattern, and zero cases:

https://godbolt.org/z/9Kecrd
Comment 6 Vitaly Buka 2021-02-25 12:10:40 PST
> Assignments performed in switch statements are indeed unreachable, and a
> local variable declared in a switch remains uninitialized.
> But aren't we trying to guarantee that uninitialized locals are now
> initialized? Asking the users to proactively fix their code kind of
> contradicts with the goal of giving them the flag :)

Isn't the feature a mitigation to reduce probability of exploits on these kind of bugs and not language feature which guaranty initialization?

Users are still have to fix them.
Comment 7 Kees Cook 2021-02-25 12:18:14 PST
-ftrivial-auto-var-init=pattern|zero should be deterministic for all automatic variables. Currently it is not (this case), but it also doesn't even warn about it. It's totally silent. So a minimum solution should at least warn about the condition, if it doesn't fix it.
Comment 8 Vitaly Buka 2021-02-25 12:46:50 PST
(In reply to Kees Cook from comment #7)
> -ftrivial-auto-var-init=pattern|zero should be deterministic for all
> automatic variables. Currently it is not (this case), but it also doesn't
> even warn about it. It's totally silent. So a minimum solution should at
> least warn about the condition, if it doesn't fix it.

Either will be improvement, just saying that "guaranty" is too strong.

Probably JumpScopeChecker can be more strict with -ftrivial-auto-var-init.