Bug 38908 - [4.4 regression] Unexplained "'<anonymous>' is used uninitialized in this function" warning in cc1plus -m64
Summary: [4.4 regression] Unexplained "'<anonymous>' is used uninitialized in this fun...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.4.0
Assignee: Jason Merrill
URL:
Keywords: diagnostic, missed-optimization
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2009-01-18 22:42 UTC by simon_baldwin
Modified: 2009-10-16 13:36 UTC (History)
10 users (show)

See Also:
Host: i386-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: i386-unknown-linux-gnu
Known to work: 4.3.2
Known to fail:
Last reconfirmed: 2009-03-05 03:54:13


Attachments
Failing testcase (160.13 KB, application/x-gzip)
2009-01-28 17:27 UTC, Wolfgang Bangerth
Details

Note You need to log in before you can comment on or make changes to this bug.
Description simon_baldwin 2009-01-18 22:42:33 UTC
cc1plus prints

x.cc: In member function 'typename S10<T>::S12 S2::S5<T>::S13() [with T = S8 ()()]':
x.cc:15: error: '<anonymous>' is used uninitialized in this function

in a gcc 4.4 trunk compilation of the C++ appended below for a 64-bit target.  It's unclear what precisely is uninitialized here, and the same warning does not appear for 32-bit targets.  This warning also doesn't appear in gcc 4.3.1 or earlier.

$ cat x.cc
struct S8 { template<typename T> S8(T) { } };

template<typename T> struct S10;
template<typename T> struct S10<T()> { typedef T S12; typedef S8 S1(); };

template<typename T> struct S3 { };
template<typename T> struct S11 { S11(S3<T>); };

struct S2
{
  template<typename T> operator S11<T>() { return S11<T>(S5<T>()); }
  template<typename T> struct S5:public S3<T>
  {
    virtual typename S10<T>::S12 S13() {
      return 0;
    }
  };
};

template<typename T> S11<T> S6(S3<T>) { return S11<T>(S3<T>()); }
template<typename S12> struct S7 { typedef S12 S15(); };

struct S4
{
  template<typename T> operator S11<T>()
  {
    struct S14:public S3<T>
    { 
      S14(S2 x):S11_(x) { }
      S11<typename S7<typename S10<T>::S12>::S15> S11_;
    };
    return S6(S14(S11_));
  }
  S2 S11_;
};

struct S9
{
  template<typename F> operator S11<F>() { return S11<F>(S14<F>(S11_)); }
  template<typename F> struct S14:public S3<F>
  {
    S14(S4 x):S11_(x) { }
    S11<typename S10<F>::S1> S11_;
  };
  S4 S11_;
};

void S15(S11<void()>);
void S16() { S9 x; S15(x); }

$ cc1plus -Werror -m32 -version -quiet x.cc -O1 -Wuninitialized -o /dev/null
GNU C++ (GCC) version 4.4.0 20090118 (experimental) (x86_64-unknown-linux-gnu)
   compiled by GNU C version 4.0.3 (Ubuntu 4.0.3-1ubuntu5), GMP version 4.2.2, MPFR version 2.3.1.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 3943547ae1329ecd45283a86831b8d94
$ echo $?
0

$ cc1plus -Werror -m64 -version -quiet x.cc -O1 -Wuninitialized -o /dev/null
GNU C++ (GCC) version 4.4.0 20090118 (experimental) (x86_64-unknown-linux-gnu)
   compiled by GNU C version 4.0.3 (Ubuntu 4.0.3-1ubuntu5), GMP version 4.2.2, MPFR version 2.3.1.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 3943547ae1329ecd45283a86831b8d94
cc1plus: warnings being treated as errors
x.cc: In member function 'typename S10<T>::S12 S2::S5<T>::S13() [with T = S8 ()()]':
x.cc:15: error: '<anonymous>' is used uninitialized in this function
$ echo $?
1
Comment 1 Benjamin Kosnik 2009-01-21 22:24:03 UTC
I see this as well. See 38851 for more spurious uninitialized warnings. 

This is a regression from 4.3, and IMHO is not minor.
Comment 2 Benjamin Kosnik 2009-01-21 22:41:23 UTC
fix summary
Comment 3 Wolfgang Bangerth 2009-01-23 19:26:33 UTC
I see this as well. It triggers a ton of time in boost::graph code.
I think it should have higher priority than P3.
W.
Comment 4 Richard Biener 2009-01-25 18:02:09 UTC
  struct S8 D.2460;
  struct S8 D.2470;

<bb 2>:
  # VUSE <D.2460_1(D)>
  # D.2470_3 = VDEF <D.2470_2(D)>
  D.2470 = D.2460;

and struct S8 is empty.

This is a dup of PR38851 which has a smaller testcase.

*** This bug has been marked as a duplicate of 38851 ***
Comment 5 Wolfgang Bangerth 2009-01-27 16:00:46 UTC
Richard,
this isn't a duplicate of PR 38851: while the testcase there indeed now
passes, the one in the current PR still fails.

Best
 Wolfgang
Comment 6 Richard Biener 2009-01-27 16:11:53 UTC
Well, it is a duplicate really, just this testcase involves one more case:

  # VUSE <D.2044_1(D)>
  # <retval>_3 = VDEF <<retval>_2(D)>
  __comp_ctor  (&<retval>, D.2044);

where the uninitialized aggregate use appears as a function argument.  While
I would like to have registers for these, simply disabling the warning for
calls looks easier.

I am testing a patch.
Comment 7 Richard Biener 2009-01-28 09:36:55 UTC
Fixed.
Comment 8 Richard Biener 2009-01-28 09:36:58 UTC
Subject: Bug 38908

Author: rguenth
Date: Wed Jan 28 09:36:41 2009
New Revision: 143722

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143722
Log:
2009-01-28  Richard Guenther  <rguenther@suse.de>

	PR middle-end/38908
	* tree-ssa.c (warn_uninitialized_var): Do not warn for seemingly
	uninitialized aggregate uses in call arguments.

	* g++.dg/warn/Wuninitialized-2.C: New testcase.

Added:
    trunk/gcc/testsuite/g++.dg/warn/Wuninitialized-2.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa.c

Comment 9 Wolfgang Bangerth 2009-01-28 17:27:41 UTC
Created attachment 17203 [details]
Failing testcase

Richard,
I hate to break the news to you but there are even more cases. Attached
is a file that produces this warning:
----------------------------
dof_renumbering.ii:51892: warning: '<anonymous>' may be used uninitialized in this function
dof_renumbering.ii:51892: note: '<anonymous>' was declared here
----------------------------
The warning comes from using the unnamed object 'dfs_visitor()', which is
of this type:
----------------------------
  struct empty
  {};
  

  struct dfs_visitor {
    dfs_visitor() { }
    dfs_visitor(empty vis) : m_vis(vis) { }
    empty m_vis;
  };
-------------------

I wished I could come up with a smaller testcase, this one is fairly
lengthy, though everything of importance happens in the last 20 or so lines.

Best
 Wolfgang
Comment 10 Wolfgang Bangerth 2009-01-28 17:28:02 UTC
Re-open
Comment 11 Richard Biener 2009-01-28 20:49:05 UTC
# VUSE <D.86121_223(D)> { D.86121 }
# vis_224 = VDEF <vis_91> { vis }
vis = D.86121;

cp_expr_size returns 1 for the objects.

 <var_decl 0xb5eb5c08 D.86121
    type <record_type 0xb62bfbc8 dfs_visitor needs-constructing type_1 type_5 type_6 QI
        size <integer_cst 0xb7cef6c8 constant 8>
        unit size <integer_cst 0xb7cef6e4 constant 1>
        align 8 symtab 0 alias set 80 canonical type 0xb62bfbc8
        fields <field_decl 0xb6bc4c38 m_vis type <record_type 0xb62bf9c0 empty>
            used nonlocal decl_3 QI file t.ii line 51866 col 11 size <integer_cst 0xb7cef6c8 8> unit size <integer_cst 0xb7cef6e4 1>
            align 8 offset_align 128
            offset <integer_cst 0xb7cef658 constant 0>
            bit offset <integer_cst 0xb7cefdc8 constant 0> context <record_type 0xb62bfbc8 dfs_visitor> chain <type_decl 0xb62bfc98 dfs_visitor>> context <namespace_decl 0xb7c2cea0 boost>
       needs-constructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown
        pointer_to_this <pointer_type 0xb62bfe38> reference_to_this <reference_type 0xb629a7b8> chain <type_decl 0xb62bfc30 dfs_visitor>>
    used ignored QI file t.ii line 51892 col 9 size <integer_cst 0xb7cef6c8 8> unit size <integer_cst 0xb7cef6e4 1>
    align 8 context <function_decl 0xb62c2300 foo> abstract_origin <var_decl 0xb6268528 D.75386>>

calling it on the m_vis member yields zero.

We change dfs_visitors empty flag to false in check_field_decls.

Short testcase:

struct empty {};

struct dfs_visitor {
    dfs_visitor() { }
    empty m_vis;
};

void bar(const dfs_visitor&);
void foo(void)
{
  dfs_visitor vis;
  dfs_visitor vis2 = vis;
  bar (vis2);
}

Note that we also end up generating code for the copy.
Comment 12 Richard Biener 2009-01-28 20:54:59 UTC
This needs to be dealt from within the frontend, possibly like Mark suggested
by inventing another predicate (I assume that CLASSTYPE_EMPTY_P is used for
some C++ standard stuff so we cannot just change that).  It may still be ok
for the expr_size langhook to return true for this kind of type:

struct empty {};
struct still_empty { empty x; };
Comment 13 Mark Mitchell 2009-01-28 23:56:16 UTC
Actually, CLASSTYPE_EMPTY_P is probably a fine thing to use for C++.  (It's of course C++ specific; you'd either need to access it via a hook, or promote to a language-independent bit.)  CLASSTYPE_EMPTY_P will not capture an array of empty objects, but that's an extreme corner-case.

Note that CLASSTYPE_EMPTY_P classes may have arbitrary size.  That's because of things like:

  struct A{};
  struct B : public A {};
  struct C : public A, public B {};

In C, you cannot put the B sub-object at the same address as the A sub-object since that would end up with two A sub-objects (the A-in-B-in-C subobject and A-in-C subobject) at the same address.  So, C will be a two-byte structure.  Obviously, you can generalize this to make arbitrarily huge empty classes.
Comment 14 rguenther@suse.de 2009-01-29 09:19:44 UTC
Subject: Re:  [4.4 regression] Unexplained "'<anonymous>' is
 used uninitialized in this function" warning in cc1plus -m64

On Wed, 28 Jan 2009, mmitchel at gcc dot gnu dot org wrote:

> ------- Comment #13 from mmitchel at gcc dot gnu dot org  2009-01-28 23:56 -------
> Actually, CLASSTYPE_EMPTY_P is probably a fine thing to use for C++.  (It's of
> course C++ specific; you'd either need to access it via a hook, or promote to a
> language-independent bit.)  CLASSTYPE_EMPTY_P will not capture an array of
> empty objects, but that's an extreme corner-case.
> 
> Note that CLASSTYPE_EMPTY_P classes may have arbitrary size.  That's because of
> things like:
> 
>   struct A{};
>   struct B : public A {};
>   struct C : public A, public B {};
> 
> In C, you cannot put the B sub-object at the same address as the A sub-object
> since that would end up with two A sub-objects (the A-in-B-in-C subobject and
> A-in-C subobject) at the same address.  So, C will be a two-byte structure. 
> Obviously, you can generalize this to make arbitrarily huge empty classes.

Ok.  But, as opposed to inheritance, inserting empty members seems to
make a class non-empty:

struct A {};
struct B { A x; };

even if in the single-member case I would have expected it to behave
like the single-inheritance case really.  Note that cp_expr_size boils
down to checking CLASSTYPE_EMPTY_P already, but in the member case
doesn't seem to map to "does not need initialization".

Richard.
Comment 15 hjl@gcc.gnu.org 2009-01-29 17:43:44 UTC
Subject: Bug 38908

Author: hjl
Date: Thu Jan 29 17:43:14 2009
New Revision: 143765

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143765
Log:
2009-01-29  H.J. Lu  <hongjiu.lu@intel.com>

	2009-01-28  Richard Guenther  <rguenther@suse.de>

	PR middle-end/38908
	* g++.dg/warn/Wuninitialized-2.C: New testcase.

	2009-01-27  Daniel Kraft  <d@domob.eu>

	PR fortran/38883
	* gfortran.dg/mvbits_6.f90:  New test.
	* gfortran.dg/mvbits_7.f90:  New test.
	* gfortran.dg/mvbits_8.f90:  New test.

	2009-01-21  Daniel Kraft  <d@domob.eu>

	PR fortran/38887
	* gfortran.dg/mvbits_5.f90:  New test.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/g++.dg/warn/Wuninitialized-2.C
      - copied unchanged from r143764, trunk/gcc/testsuite/g++.dg/warn/Wuninitialized-2.C
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/mvbits_5.f90
      - copied unchanged from r143764, trunk/gcc/testsuite/gfortran.dg/mvbits_5.f90
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/mvbits_6.f90
      - copied unchanged from r143764, trunk/gcc/testsuite/gfortran.dg/mvbits_6.f90
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/mvbits_7.f90
      - copied unchanged from r143764, trunk/gcc/testsuite/gfortran.dg/mvbits_7.f90
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/mvbits_8.f90
      - copied unchanged from r143764, trunk/gcc/testsuite/gfortran.dg/mvbits_8.f90
Modified:
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog

Comment 16 Mark Mitchell 2009-02-02 07:15:31 UTC
Subject: Re:  [4.4 regression] Unexplained "'<anonymous>' is
 used uninitialized in this function" warning in cc1plus -m64

rguenther at suse dot de wrote:

> Ok.  But, as opposed to inheritance, inserting empty members seems to
> make a class non-empty:
> 
> struct A {};
> struct B { A x; };

I'm surprised by that too, but the ABI definition is:

empty class

    A class with no non-static data members other than zero-width
bitfields, no virtual functions, no virtual base classes, and no
non-empty non-virtual proper base classes.

Here, we do have a non-static data member that is not a zero-width
bitfield, so I guess this isn't an empty class.

So, CLASSTYPE_EMPTY_P would be a conservative approximation at present,
but we need a new bit to capture the broader thing that is desired here.

Comment 17 Jason Merrill 2009-03-05 14:10:23 UTC
Subject: Bug 38908

Author: jason
Date: Thu Mar  5 14:10:07 2009
New Revision: 144643

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144643
Log:
        PR c++/38908
        * class.c (is_really_empty_class): New fn.
        * cp-tree.h: Declare it.
        * cp-objcp-common.c (cp_expr_size): Use it.

Added:
    trunk/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/class.c
    trunk/gcc/cp/cp-objcp-common.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/testsuite/ChangeLog

Comment 18 Jason Merrill 2009-03-05 14:32:42 UTC
Fixed.
Comment 19 Andreas Beckmann 2009-10-16 13:13:42 UTC
some cases where this warning still occurs in 4.4 are documented in #40146