https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83871

            Bug ID: 83871
           Summary: wrong code for attribute const and pure on distinct
                    template specializations
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

I'm sure the root case of this bug is the same as that of pr83503 but the
latter is about a warning and this one is about GCC emitting the wrong code and
so it might be worth tracking each separately (and possibly with different
priorities).  Alternatively, they can be merged as long as both test cases end
up in the test suite one the underlying bug is fixed.

Unlike in pr83504 (which was about overloads and ended up being invalid), the
test case below shows that G++ applies attribute const from the primary
template to that of specializations of the template, even though the two are
unrelated functions, and even when the specialization has the pure attribute.

This bug affects all GCC releases.  Clang 3.5 and older and ICC behave
correctly.  Clang 3.6 and later has the same bug as GCC.

$ cat pr83503.C && gcc -O2 -S -Wall pr83503.C -fdump-tree-optimized=/dev/stdout
extern "C" void abort ();

void* __attribute__ ((const)) f (void*);

template <class T>
T __attribute__ ((const)) g (T);

int i;

int __attribute__ ((pure))
f (int);   // body could be: { return i; }

template <>
int __attribute__ ((pure))
g<int> (int);   // body could be: { return i; }


void call_pure_overload (int x)
{
  i = 1;
  int i0 = f (x);   // call made (good)
  i = 2;
  int i1 = f (x);   // call made (good)

  if (i0 == i1)     // retained
    abort ();
}


void call_pure_specialization (int x)
{
  i = 1;
  int i0 = g (x);   // call eliminated (wrong)
  i = 2;
  int i1 = g (x);   // call eliminated (wrong)

  if (i0 == i1)     // folded to false (wrong)
    abort ();
}

;; Function void call_pure_overload(int) (_Z18call_pure_overloadi,
funcdef_no=0, decl_uid=2267, cgraph_uid=0, symbol_order=1)

void call_pure_overload(int) (int x)
{
  int _4;
  int _6;

  <bb 2>:
  i = 1;
  _4 = f (x_3(D));
  i = 2;
  _6 = f (x_3(D));
  if (_4 == _6)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  abort ();

  <bb 4>:
  return;

}



;; Function void call_pure_specialization(int) (_Z24call_pure_specializationi,
funcdef_no=1, decl_uid=2272, cgraph_uid=1, symbol_order=2) (executed once)

void call_pure_specialization(int) (int x)
{
  <bb 2>:
  i = 2;
  abort ();

}

Reply via email to