Bug 38271 - [4.4 Regression] Spurious / missing "... used uninitialized in this function" warning
Summary: [4.4 Regression] Spurious / missing "... used uninitialized in this function"...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2008-11-26 02:47 UTC by Dmitry Gorbachev
Modified: 2008-12-10 17:30 UTC (History)
2 users (show)

See Also:
Host:
Target: i686-*-*
Build:
Known to work: 4.3.2
Known to fail:
Last reconfirmed: 2008-11-26 02:54:24


Attachments
testcase (105 bytes, text/plain)
2008-11-26 02:48 UTC, Dmitry Gorbachev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Gorbachev 2008-11-26 02:47:05 UTC
gcc -S -O1 -Wuninitialized uninitialized.c

GCC 4.4.0 20081121:
  warning: 's' is used uninitialized in this function

GCC 4.3.2:
  warning: ‘i’ may be used uninitialized in this function
Comment 1 Dmitry Gorbachev 2008-11-26 02:48:53 UTC
Created attachment 16772 [details]
testcase
Comment 2 Andrew Pinski 2008-11-26 02:54:24 UTC
What the *#$^*(#^&$*(:
  SR.3_5 = p_1(D)->c;
  SR.4_6 = VIEW_CONVERT_EXPR<long long unsigned int>(*p_1(D));
  SR.4_7 = SR.4_6 & 4294967295;
  SR.5_8 = (unsigned int) SR.4_7;
  s.0.c ={v} SR.3_5;
  SR.6_10 = VIEW_CONVERT_EXPR<long long unsigned int>(s.0);
  SR.7_11 = SR.6_10 & 0x0ffffffff00000000;
  SR.8_12 = (long long unsigned int) SR.5_8;
  SR.9_13 = SR.7_11 | SR.8_12;
  s.0 ={v} VIEW_CONVERT_EXPR<struct xxx>(SR.9_13);

This is so wrong.
Comment 3 Richard Biener 2008-11-26 10:00:51 UTC
Doesn't happen on 64bit x86_64.  Testcase which doesn't warn with 4.3:

struct xxx {
    short a;
    short b;
    void *c;
};

void bar(struct xxx);

void foo(struct xxx *p, int i)
{
  struct xxx s = *p;
  if (s.a) i++;
  bar(s);
}

but indeed, SRA does bullshit here, cost-wise and correctness-wise.
Comment 4 Jakub Jelinek 2008-12-03 16:28:00 UTC
I can't reproduce this any longer since
http://gcc.gnu.org/viewcvs?view=rev&revision=142396
Comment 5 Richard Biener 2008-12-03 16:38:24 UTC
Still warns for

truct xxx {
    short a;
    short b;
    void *c;
};

void bar(struct xxx);

void foo(struct xxx *p, int i)
{
  struct xxx s0 = *p;
  struct xxx s = s0;
  if (s.a) i++;
  bar(s);
}

at -O -m32 -Wuninitialized.
Comment 6 Richard Biener 2008-12-05 12:57:28 UTC
This is sra_build_assignment/sra_build_bf_assignments way of "lowering" a
BIT_FIELD_REF to integer arithmetic.  We hit the !INTEGRAL_TYPE_P (TREE_TYPE (var)) paths and for

  BIT_FIELD_REF <*p_1(D), 32, 0>

we create VIEW_CONVERT_EXPR <long long> (*p) and extract the lower/upper 32
bits by shifting and masking.  This obviously "uses" possibly uninitialized
parts of *p or s0.  The problem here is that we interestingly split the
initialization of s0 to the upper part

  s0.c ={v} s0$c_7;

and the lower part

  SR.3_8 = VIEW_CONVERT_EXPR<long long unsigned int>(s0);
  SR.4_9 = SR.3_8 & 0xffffffff00000000;
  SR.5_10 = (long long unsigned int) s0$B0F32_5;
  SR.6_11 = SR.4_9 | SR.5_10;
  s0 ={v} VIEW_CONVERT_EXPR<struct xxx>(SR.6_11);

this is likely because SRA really wants to have two 32bit fields but it
cannot deal with the larger struct with a VIEW_CONVERT_EXPR.

With just disabling all these code-paths we get

<bb 2>:
  s0$B0F32_4 = 0;
  s0$c_5 = p_1(D)->c;
  s0$B0F32_6 = BIT_FIELD_REF <*p_1(D), 32, 0>;
  s0.c ={v} s0$c_5;
  BIT_FIELD_REF <s0, 32, 0> ={v} s0$B0F32_6;
  s ={v} s0;
  s$a_7 = s.a;
  D.1242_2 = s$a_7;

and no warning.  But of course we now have bitfield refs that are not optimized
(not scalarizing in this case would be better).  Of course even with the
current scalarization we finally arrive with

<bb 2>:
  # VUSE <SMT.16_13(D)>
  s0$c_7 = p_1(D)->c;
  # VUSE <SMT.16_13(D)>
  D.1249_4 = VIEW_CONVERT_EXPR<long long unsigned int>(*p_1(D));
  s0$B0F32_5 = (unsigned int) D.1249_4;
  # VUSE <s0_14(D)>
  SR.21_24 = VIEW_CONVERT_EXPR<long long unsigned int>(s0);
  SR.22_25 = SR.21_24 & 0xffffffff00000000;
  # s0_28 = VDEF <s0_14(D)>
  s0 = VIEW_CONVERT_EXPR<struct xxx>(SR.22_25);
  # s0_29 = VDEF <s0_28>
  s0.c = s0$c_7;
  # VUSE <s0_29>
  SR.3_8 = VIEW_CONVERT_EXPR<long long unsigned int>(s0);
  SR.4_9 = SR.3_8 & 0xffffffff00000000;
  SR.5_10 = (long long unsigned int) s0$B0F32_5;
  SR.6_11 = SR.5_10 | SR.4_9;
  s0$B0F32_21 = (unsigned int) SR.6_11;
  s0$c_30 = VIEW_CONVERT_EXPR<struct xxx>(SR.6_11).c;
  # VUSE <s0_29>
  SR.25_31 = VIEW_CONVERT_EXPR<long long unsigned int>(s0);
  SR.26_32 = SR.25_31 & 0xffffffff00000000;
  SR.27_33 = (long long unsigned int) s0$B0F32_21;
  SR.28_34 = SR.27_33 | SR.26_32;
  # s0_35 = VDEF <s0_29>
  s0 = VIEW_CONVERT_EXPR<struct xxx>(SR.28_34);
  # s0_36 = VDEF <s0_35>
  s0.c = s0$c_30;
  # VUSE <s0_36>
  # s_18 = VDEF <s_17(D)>
  s = s0;
  # VUSE <s_18>
  s$a_37 = s.a;
  # s_39 = VDEF <s_18>
  s.a = s$a_37;
  # VUSE <s_39>
  # SMT.16_20 = VDEF <SMT.16_13(D)>
  bar (s);
  return;

because we seem to scalarize again.  Ugh.
Comment 7 Richard Biener 2008-12-05 13:05:12 UTC
The following would make SRA only combine all of the struct or nothing.  That
avoids these messy situations:

Index: tree-sra.c
===================================================================
--- tree-sra.c	(revision 142469)
+++ tree-sra.c	(working copy)
@@ -1695,7 +1695,10 @@ try_instantiate_multiple_fields (struct 
 
   gcc_assert (~alchk < align);
 
-  /* Create the field group as a single variable.  */
+  /* Create the field group as a single variable if the group covers
+     the whole element.  */
+  if (size != TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (elt->element))))
+    return f;
 
   /* We used to create a type for the mode above, but size turns
      to be out not of mode-size.  As we need a matching type
Comment 8 Dmitry Gorbachev 2008-12-08 20:34:21 UTC
(In reply to comment #7)

The patch causes segfault. This is how it happens:

tree-sra.c:1612
      for (f = TYPE_FIELDS (elt->type);
           f; f = TREE_CHAIN (f))
        {

tree-sra.c:1700
  if (size != TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (elt->element))))
    return f; // NULL

tree-sra.c:1764
        for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
          if (TREE_CODE (f) == FIELD_DECL)
            {
              tree last = try_instantiate_multiple_fields (elt, f);

              if (last != f)
                {
                  f = last;
                  continue;
                }
Comment 9 Alexandre Oliva 2008-12-10 17:22:11 UTC
Subject: Bug 38271

Author: aoliva
Date: Wed Dec 10 17:20:50 2008
New Revision: 142651

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142651
Log:
gcc/ChangeLog:
PR middle-end/38271
* tree-sra.c (sra_build_bf_assignment): Avoid warnings for
variables initialized from SRAed bit fields.
gcc/testsuite/ChangeLog:
PR middle-end/38271
* gcc.dg/torture/pr38271.c: New.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr38271.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-sra.c

Comment 10 Alexandre Oliva 2008-12-10 17:30:52 UTC
Fixed.