https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79825
Bug ID: 79825
Summary: [7 Regression] Uninitialized uses in aggregate copies
of empty structs (missed DCE in C++ gimplify)
Product: gcc
Version: 7.0.1
Status: UNCONFIRMED
Keywords: diagnostic, missed-optimization
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: rguenth at gcc dot gnu.org
Target Milestone: ---
With
struct A;
struct B {
B(A);
};
struct C {
template <typename PassT> void m_fn1(PassT p1) { new B(p1); }
};
struct A {};
void fn1() {
C a;
a.m_fn1(A());
}
we see
;; Function void C::m_fn1(PassT) [with PassT = A] (null)
;; enabled by -tree-original
<<cleanup_point <<< Unknown tree: expr_stmt
(void) (TARGET_EXPR <D.2394, TARGET_EXPR <D.2392, p1>;, <<< Unknown tree:
empty_class_expr >>>;>;, TARGET_EXPR <D.2373, operator new (1)>;, try
{
B::B ((struct B *) D.2373, *(struct A &) &D.2394);
}
gimplified to
void C::m_fn1(PassT) [with PassT = A] (struct C * const this, struct A p1)
{
struct A D.2394;
struct A D.2392;
struct A D.2399;
void * D.2373;
D.2394 = D.2399;
try
{
...
where this copy of an "empty" class prevails until .optimized.
The C++ gimplifier is supposed to eliminate such copies as the middle-end
sees 1-byte aggregates where it cannot readily eliminate anything.
The new fancy uninit warning now warns here as well:
t.C: In member function ‘void C::m_fn1(PassT) [with PassT = A]’:
t.C:6:56: warning: ‘<anonymous>’ is used uninitialized in this function
[-Wuninitialized]
template <typename PassT> void m_fn1(PassT p1) { new B(p1); }
^~~
with the old machinery we only didn't warn because we for some reason
disregarded any aggregate uses:
use = gimple_vuse (stmt);
if (use
&& gimple_assign_single_p (stmt)
&& !gimple_vdef (stmt)
^^^^^^^
&& SSA_NAME_IS_DEFAULT_DEF (use))