From: Nathan Chancellor <natechancel...@gmail.com>

[ Upstream commit c2869aafe7191d366d74c55cb8a93c6d0baba317 ]

clang warns:

arch/mips/kernel/branch.c:148:8: error: variable 'bc_false' is used
uninitialized whenever switch case is taken
[-Werror,-Wsometimes-uninitialized]
                case mm_bc2t_op:
                     ^~~~~~~~~~
arch/mips/kernel/branch.c:157:8: note: uninitialized use occurs here
                        if (bc_false)
                            ^~~~~~~~
arch/mips/kernel/branch.c:149:8: error: variable 'bc_false' is used
uninitialized whenever switch case is taken
[-Werror,-Wsometimes-uninitialized]
                case mm_bc1t_op:
                     ^~~~~~~~~~
arch/mips/kernel/branch.c:157:8: note: uninitialized use occurs here
                        if (bc_false)
                            ^~~~~~~~
arch/mips/kernel/branch.c:142:4: note: variable 'bc_false' is declared
here
                        int bc_false = 0;
                        ^
2 errors generated.

When mm_bc1t_op and mm_bc2t_op are taken, the bc_false initialization
does not happen, which leads to a garbage value upon use, as illustrated
below with a small sample program.

$ mipsel-linux-gnu-gcc --version | head -n1
mipsel-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0

$ clang --version | head -n1
ClangBuiltLinux clang version 9.0.0 (git://github.com/llvm/llvm-project
544315b4197034a3be8acd12cba56a75fb1f08dc) (based on LLVM 9.0.0svn)

$ cat test.c
 #include <stdio.h>

 static void switch_scoped(int opcode)
 {
         switch (opcode) {
         case 1:
         case 2: {
                 int bc_false = 0;

                 bc_false = 4;
         case 3:
         case 4:
                 printf("\t* switch scoped bc_false = %d\n", bc_false);
         }
         }
 }

 static void function_scoped(int opcode)
 {
         int bc_false = 0;

         switch (opcode) {
         case 1:
         case 2: {
                 bc_false = 4;
         case 3:
         case 4:
                 printf("\t* function scoped bc_false = %d\n", bc_false);
         }
         }
 }

 int main(void)
 {
         int opcode;

         for (opcode = 1; opcode < 5; opcode++) {
                 printf("opcode = %d:\n", opcode);
                 switch_scoped(opcode);
                 function_scoped(opcode);
                 printf("\n");
         }

         return 0;
 }

$ mipsel-linux-gnu-gcc -std=gnu89 -static test.c && \
  qemu-mipsel a.out
opcode = 1:
        * switch scoped bc_false = 4
        * function scoped bc_false = 4

opcode = 2:
        * switch scoped bc_false = 4
        * function scoped bc_false = 4

opcode = 3:
        * switch scoped bc_false = 2147483004
        * function scoped bc_false = 0

opcode = 4:
        * switch scoped bc_false = 2147483004
        * function scoped bc_false = 0

$ clang -std=gnu89 --target=mipsel-linux-gnu -m32 -static test.c && \
  qemu-mipsel a.out
opcode = 1:
        * switch scoped bc_false = 4
        * function scoped bc_false = 4

opcode = 2:
        * switch scoped bc_false = 4
        * function scoped bc_false = 4

opcode = 3:
        * switch scoped bc_false = 2147483004
        * function scoped bc_false = 0

opcode = 4:
        * switch scoped bc_false = 2147483004
        * function scoped bc_false = 0

Move the definition up so that we get the right behavior and mark it
__maybe_unused as it will not be used when CONFIG_MIPS_FP_SUPPORT
isn't enabled.

Fixes: 6a1cc218b9cc ("MIPS: branch: Remove FP branch handling when 
CONFIG_MIPS_FP_SUPPORT=n")
Link: https://github.com/ClangBuiltLinux/linux/issues/603
Signed-off-by: Nathan Chancellor <natechancel...@gmail.com>
Signed-off-by: Paul Burton <paul.bur...@mips.com>
Cc: Ralf Baechle <r...@linux-mips.org>
Cc: James Hogan <jho...@kernel.org>
Cc: Nick Desaulniers <ndesaulni...@google.com>
Cc: linux-m...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: clang-built-li...@googlegroups.com
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 arch/mips/kernel/branch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 180ad081afcf9..c2d88c1dcc0f8 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -58,6 +58,7 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct 
mm_decoded_insn dec_insn,
                       unsigned long *contpc)
 {
        union mips_instruction insn = (union mips_instruction)dec_insn.insn;
+       int __maybe_unused bc_false = 0;
 
        if (!cpu_has_mmips)
                return 0;
@@ -139,7 +140,6 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct 
mm_decoded_insn dec_insn,
 #ifdef CONFIG_MIPS_FP_SUPPORT
                case mm_bc2f_op:
                case mm_bc1f_op: {
-                       int bc_false = 0;
                        unsigned int fcr31;
                        unsigned int bit;
 
-- 
2.20.1

Reply via email to