Bug 64614 - bogus used initialized warning (in gcc 4.9.2); switch statement versus &
Summary: bogus used initialized warning (in gcc 4.9.2); switch statement versus &
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2015-01-15 16:21 UTC by Dr. David Alan Gilbert
Modified: 2015-01-19 09:41 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 5.0
Known to fail: 2.95.2, 3.4.6, 4.1.2, 4.9.2
Last reconfirmed:


Attachments
preliminary patch (1.36 KB, patch)
2015-01-16 10:31 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dr. David Alan Gilbert 2015-01-15 16:21:47 UTC
gcc t.c -O1 -Wall -Wextra

(Any -O value 1 or above)

t.c: In function ‘foo’:
t.c:15:15: warning: ‘tmp’ may be used uninitialized in this function [-Wmaybe-uninitialized]
       tmp[11] = 15;
               ^
(This code is similar to qemu's arch_init.c/ram_load loop where I hit this)

Gcc doesn't seem to be spotting that the tmp = baz initialiser will always happen for the switch cases that use tmp.

this is using the Fedora 21 gcc: gcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC) 
package: gcc-4.9.2-1.fc21.x86_64
It doesn't trigger for me on gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) 


char *foo(int bar, char *baz)
{
  char *tmp;

  if (bar & 3) {
      tmp = baz;
  }
  
  switch (bar) {
  case 1:
      tmp[5] = 7;
      break;

  case 2:
      tmp[11] = 15;
      break;

  default:
      tmp = 0;
      break;
  }

  return tmp;
}
Comment 1 Marek Polacek 2015-01-15 16:27:02 UTC
We have tons of these -W*uninitialized bugs, so there's likely a dup.
Comment 2 Dr. David Alan Gilbert 2015-01-15 16:32:24 UTC
(In reply to Marek Polacek from comment #1)
> We have tons of these -W*uninitialized bugs, so there's likely a dup.

Yep, it's possible - I couldn't find an obvious match; but two things to note that might make this case easier to track down:
   a) It seems a regression from 4.8.3 to 4.9.2
   b) To me it seems specific to the  if/switch combination
 
Dave
Comment 3 Jakub Jelinek 2015-01-15 17:22:59 UTC
I can't reproduce your claim about 4.8.  This warns for me with all compilers I've tried back from 4.0 till latest trunk, including 4.8 and many others.
Comment 4 Dr. David Alan Gilbert 2015-01-15 17:30:24 UTC
Apologies, yes, you're right, it does also do it on 4.8.3.
Sorry again, I think I probably missed either the -O or -Wall when I tried to reproduce on 4.8.3.
Comment 5 Richard Biener 2015-01-16 10:31:19 UTC
Created attachment 34461 [details]
preliminary patch

I think the uninit pass doesn't even try to handle switch case input conditions
(convert_control_dep_chain_into_preds).  Nor does predicate handling deal with
bar & 3 predicates.

Preliminary patch attached - still needs to handle the default case - but
it seems we don't warn about the return value with the patch.

With the patch:

[CHECK] Found def edge 1 in tmp_1 = PHI <tmp_6(D)(3), baz_7(D)(8)>
[BEFORE SIMPLICATION -- [USE]:
MEM[(char *)tmp_1 + 11B] = 15;
is guarded by :

bar_4(D) == 2

[BEFORE SIMPLICATION -- [DEF]:
tmp_1 = PHI <tmp_6(D)(3), baz_7(D)(8)>
is guarded by :

_5 != 0

[AFTER NORMALIZATION -- [DEF]:
tmp_1 = PHI <tmp_6(D)(3), baz_7(D)(8)>
is guarded by :

bar_4(D) & 3
Comment 6 Richard Biener 2015-01-16 13:11:57 UTC
Fails for all versions I tested btw, so nowhere near a regression.
Comment 7 Richard Biener 2015-01-16 13:26:44 UTC
Author: rguenth
Date: Fri Jan 16 13:26:10 2015
New Revision: 219739

URL: https://gcc.gnu.org/viewcvs?rev=219739&root=gcc&view=rev
Log:
2015-01-16  Richard Biener  <rguenther@suse.de>

	PR middle-end/64614
	* tree-ssa-uninit.c: Include tree-cfg.h.
	(MAX_SWITCH_CASES): New define.
	(convert_control_dep_chain_into_preds): Handle switch statements.
	(is_pred_expr_subset_of): Handle x == CST vs. (x & CST) != 0.
	(normalize_one_pred_1): Do not split bit-manipulations.
	Record (x & CST).

	* gcc.dg/uninit-18.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/uninit-18.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-uninit.c
Comment 8 Dr. David Alan Gilbert 2015-01-16 18:05:20 UTC
Richard: Thanks for the fix, and apologies again for my screwed up regression test.
Comment 9 Richard Biener 2015-01-19 09:41:45 UTC
Fixed on trunk.