Bug 68939 - ICE or wrong code with OpenMP privatization of reference to VLAs
Summary: ICE or wrong code with OpenMP privatization of reference to VLAs
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: openmp, wrong-code
Depends on:
Blocks: C++VLA
  Show dependency treegraph
 
Reported: 2015-12-16 15:15 UTC by Jakub Jelinek
Modified: 2025-11-26 21:24 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-09-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2015-12-16 15:15:07 UTC
int main ()
{
  int y = 6;
  int a[y - 2];
  int (&c)[y - 2] = a;
  c[0] = 111;

  #pragma omp target private (c)
  c[0] = 222;

  return 0;
}

results in wrong-code being generated (use of uninitialized variable in the outlined region for determining the size of the private c size), and in ICE with say:
int main ()
{
  int y = 6;
  int a[y - 2];
  int (&c)[y - 2] = a;
  c[0] = 111;

  #pragma omp parallel private (c)
  #pragma omp single
    c[0] = 222;
  return 0;
}
Following is also wrong-code.
int main ()
{
  int y = 6;
  int a[y - 2];
  typedef int T[y - 2];
  T &c = a;
  c[0] = 111;

  #pragma omp target private (c)
  c[0] = 222;

  return 0;
}

I believe the problem is because of some Ada mess the gimplifier no longer recurses in gimplify_type_sizes on REFERENCE_TYPE.  Well, for all we care, it would be enough to handle the toplevel REFERENCE_TYPE and nothing else.
But, if we can't change gimplify_type_sizes because of Ada, perhaps we should tweak the C++ FE so that it arranges to emit a DECL_EXPR with a dummy TYPE_DECL so that the referenced type sizes are gimplified?
Comment 1 Jakub Jelinek 2015-12-16 15:43:22 UTC
Adding openmp keyword, so that it not forgotten by me, but I see various other issues.
E.g. on the following testcase, with -W -Wall and foo2 ifdefed out I see:
pr68939.C: In function ‘void foo(int)’:
pr68939.C:16:10: warning: ‘<anonymous>’ may be used uninitialized in this function [-Wmaybe-uninitialized]
       T1 b;
          ^
(and with foo2 not ifdefed out a warning in foo2 only, not in foo, strange), and the gimple dump shows that the temporaries for the VLA type are only initialized in the lexical block containing the a variable, but not the other one:

int bar (void);
void baz (int *, long);
void
foo (int x)
{
  typedef int T1[bar () + x];
  if (x == 6)
    {
      T1 a;
      a[0] = 8;
      a[bar () + 5] = 9;
      baz (a, sizeof (a));
    }
  else if (x == 8)
    {
      T1 b;
      b[0] = 9;
      b[bar () + 7] = 10;
      baz (b, sizeof (b));
    }
}
void
foo2 (int x)
{
  typedef int T1[bar () + x];
  if (x == 6)
    {
      T1 buf;
      T1 &a = buf;
      a[0] = 8;
      a[bar () + 5] = 9;
      baz (a, sizeof (a));
    }
  else if (x == 8)
    {
      T1 buf;
      T1 &b = buf;
      b[0] = 9;
      b[bar () + 7] = 10;
      baz (b, sizeof (b));
    }
}

Bet we need to ensure that for the VLA types and REFERENCE_TYPE to VLAs that they for typedefs they have corresponding DECL_EXPR with TYPE_DECL already at the spot where the type is defined, and for the case in #c0, i.e. a decl with REFERENCE_TYPE to non-typedef VLA type arrange for DECL_EXPR with TYPE_DECL to that VLA type to come before the DECL_EXPR of the VAR_DECL.
Note the C FE e.g. on foo above (with foo2 containing C++ only code ifdefed out) emits a DECL_EXPR with TYPE_DECL of T1 and thus it works properly.
Jason, any thoughts on this?
Comment 2 Jakub Jelinek 2016-04-27 10:56:51 UTC
GCC 6.1 has been released.
Comment 3 Jakub Jelinek 2016-12-21 10:56:21 UTC
GCC 6.3 is being released, adjusting target milestone.
Comment 4 Richard Biener 2017-07-04 08:46:13 UTC
GCC 6.4 is being released, adjusting target milestone.