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

Kamil Dudka <kdudka at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kdudka at redhat dot com

--- Comment #6 from Kamil Dudka <kdudka at redhat dot com> ---
(In reply to rguent...@suse.de from comment #5)
> Can you bisect to a file?

The cause seems to be incorrectly compiled code of the following method:

inline
void *Collector::allocateObject(bool hasFinalizer)
{
  if (freePtr_ == &allObjectsList_)
    makeSpace();
  Object *tem = freePtr_;
  freePtr_ = freePtr_->next();
  tem->setColor(currentColor_);
  tem->hasFinalizer_ = hasFinalizer;
  if (hasFinalizer)
    tem->moveAfter(&allObjectsList_);
  return tem;
}

If I move the method from Collector.h to Collector.cxx and make it non-inline,
the problem goes away because the value of hasFinalizer is no longer known at
compile time.

Otherwise, from the modules where Collector::allocateObject() is called with
hasFinalizer equal to zero (I inspected the assembler code generated out of
primitive.cxx with/without -fno-tree-dse), the optimizer correctly drops the
code:

  if (hasFinalizer)
    tem->moveAfter(&allObjectsList_);

... but at the same time it incorrectly drops also the two assignments above
the condition:

  tem->setColor(currentColor_);
  tem->hasFinalizer_ = hasFinalizer;

Consequently one can see many uses of uninitialized values in valgrind's
output.  If I qualify the 'tem' pointer as volatile in order to suppress the
optimization, the code of openjade starts to work reliably, even if compiled
with default compilation flags, and with completely clean valgrind's output:

--- a/style/Collector.h
+++ b/style/Collector.h
@@ -138,11 +138,11 @@ void Collector::Object::moveAfter(Object *tail)
 inline
 void *Collector::allocateObject(bool hasFinalizer)
 {
   if (freePtr_ == &allObjectsList_)
     makeSpace();
-  Object *tem = freePtr_;
+  Object *volatile tem = freePtr_;
   freePtr_ = freePtr_->next();
   tem->setColor(currentColor_);
   tem->hasFinalizer_ = hasFinalizer;
   if (hasFinalizer)
     tem->moveAfter(&allObjectsList_);

Unless there is some undefined behavior in the code, this looks like a bug in
the optimizer.

Reply via email to