Skip to content
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

ftrivial-auto-var-init=pattern doesn't initialize locals in switch statement #44261

Open
ramosian-glider opened this issue Feb 14, 2020 · 9 comments
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@ramosian-glider
Copy link
Contributor

ramosian-glider commented Feb 14, 2020

Bugzilla Link 44916
Version unspecified
OS Linux
CC @fhahn,@kees,@jfbastien,@nickdesaulniers,@zygoloid,@vitalybuka

Extended Description

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
@jfbastien
Copy link
Member

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.

@ramosian-glider
Copy link
Contributor Author

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.

@kees
Copy link
Contributor

kees commented Feb 19, 2020

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;
^~

@jfbastien
Copy link
Member

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.

@kees
Copy link
Contributor

kees commented Feb 25, 2021

Updated godbolt to show uninit, pattern, and zero cases:

https://godbolt.org/z/9Kecrd

@vitalybuka
Copy link
Collaborator

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.

@kees
Copy link
Contributor

kees commented Feb 25, 2021

-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.

@vitalybuka
Copy link
Collaborator

-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.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
@kees
Copy link
Contributor

kees commented Feb 11, 2022

Same issue exists in GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104504

It would be nice to get this fixed so Clang doesn't have a blindspot here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

No branches or pull requests

4 participants