Bug 80344 - [7 Regression] -Wuninitialized triggering on a ctor on ARM
Summary: [7 Regression] -Wuninitialized triggering on a ctor on ARM
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 7.0
Assignee: Richard Biener
URL:
Keywords: diagnostic, missed-optimization
Depends on:
Blocks:
 
Reported: 2017-04-06 15:08 UTC by Marek Polacek
Modified: 2017-04-10 08:58 UTC (History)
2 users (show)

See Also:
Host:
Target: arm
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-04-07 00:00:00


Attachments
orig.ii.gz (362.10 KB, application/gzip)
2017-04-07 10:47 UTC, Marek Polacek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Marek Polacek 2017-04-06 15:08:30 UTC
With this testcase, on ARM I see:

$ ./cc1plus -quiet -I. -Wuninitialized -O q.C 
q.C: In constructor ‘B::B()’:
q.C:4:7: warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized]
   A() {}
       ^

Started with r245840.  The C++ ABI for ARM says that cdtors return "this" instead of returning void, so in .original we have

<<cleanup_point <<< Unknown tree: expr_stmt
  *(struct 
  {
    ._0 e;
    int i;
    int j;
  } &) this = {CLOBBER} >>>>>;
{
  
}
<D.4688>:;
return this;

And the last line provokes the warning.

class A {
public:
  enum { } e;
  A() {}
  int i;
  int j;
};

class B {
  B();
  A a;
};

A
fn1()
{
  return A();
}

B::B() : a(fn1()) {}
Comment 1 Richard Biener 2017-04-07 08:37:30 UTC
Confirmed.  The IL we warn about is

B::B() (struct B * const this)
{
  struct 
  {
    ._0 e;
    int i;
    int j;
  } D.4784;

  <bb 2> [100.00%]:
  D.4784 ={v} {CLOBBER};
  MEM[(struct  &)this_2(D)] = D.4784;
  return this_2(D);

and we warn about the MEM[(struct  &)this_2(D)] = D.4784; assignment.

The warning is clearly correct as the A members are not initialized.

Did you reduce a testcase too far?
Comment 2 Marek Polacek 2017-04-07 10:47:53 UTC
Created attachment 41150 [details]
orig.ii.gz

This is the original .ii file.
Comment 3 Richard Biener 2017-04-07 11:15:03 UTC
I believe this is exposed by inlining

  this_14(D)->http_ver = Http::ProtocolVersion (); [return slot optimization]

as

  D.148385 ={v} {CLOBBER};
  MEM[(struct  &)this_14(D) + 4] = D.148385;
  this_14(D)->http_ver.protocol = 1;
  this_14(D)->http_ver.major = 1;
  this_14(D)->http_ver.minor = 1;

which is

AnyP::ProtocolVersion Http::ProtocolVersion() ()
{
  <bb 2> [0.00%]:
  AnyP::ProtocolVersion::ProtocolVersion (&<retval>, 1, 1, 1);
  return <retval>;

inlined into like

AnyP::ProtocolVersion Http::ProtocolVersion() ()
{
  struct ProtocolVersion * D.148207;

  <bb 2> [100.00%]:
  MEM[(struct  &)&<retval>] ={v} {CLOBBER};
  <retval>.protocol = 1;
  <retval>.major = 1;
  <retval>.minor = 1;
  _7 = &<retval>;
  return <retval>;

not sure how this ends up happening.  Smaller testcase appreciated ;)

The above is from 029t.einline vs. 028t.inline_param1.
Comment 4 Richard Biener 2017-04-07 11:57:07 UTC
So it happens when inlining

  MEM[(struct  &)&<retval>] ={v} {CLOBBER};

and substituting &this_14(D)->http_ver for the address.  Then we trigger
id->regimplify = true; but in the end we simplify it to

  MEM[(struct  &)this_14(D) + 4] ={v} {CLOBBER};

and gimple_regimplify_operands wrecks this via

          else if (i == 2
                   && is_gimple_assign (stmt)
                   && num_ops == 2
                   && get_gimple_rhs_class (gimple_expr_code (stmt))
                      == GIMPLE_SINGLE_RHS)
            gimplify_expr (&op, &pre, NULL,
                           rhs_predicate_for (gimple_assign_lhs (stmt)),
                           fb_rvalue);

and {CLOBBER} is not is_gimple_mem_rhs_or_call.

Testing

Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c      (revision 246757)
+++ gcc/gimplify.c      (working copy)
@@ -493,7 +493,9 @@ is_gimple_mem_rhs_or_call (tree t)
   if (is_gimple_reg_type (TREE_TYPE (t)))
     return is_gimple_val (t);
   else
-    return (is_gimple_val (t) || is_gimple_lvalue (t)
+    return (is_gimple_val (t)
+           || is_gimple_lvalue (t)
+           || TREE_CLOBBER_P (t)
            || TREE_CODE (t) == CALL_EXPR);
 }
Comment 5 Richard Biener 2017-04-10 08:58:12 UTC
Fixed.
Comment 6 Richard Biener 2017-04-10 08:58:35 UTC
Author: rguenth
Date: Mon Apr 10 08:58:02 2017
New Revision: 246800

URL: https://gcc.gnu.org/viewcvs?rev=246800&root=gcc&view=rev
Log:
2017-04-10  Richard Biener  <rguenther@suse.de>

	PR middle-end/80344
	* gimplify.c (is_gimple_mem_rhs_or_call): Allow CLOBBERs.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimplify.c