Opened 9 years ago

Closed 9 years ago

#9139 closed Bugs (fixed)

attribute_value_set.cpp fails to build correctly in Sun Studio 12.3

Reported by: Brian Vandenberg <phantall+boost@…> Owned by: Andrey Semashev
Milestone: To Be Determined Component: log
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc: phantall+boost@…

Description

When building boost::log, I'm getting the following error:

"libs/log/src/attribute_value_set.cpp", line 213: Error: m_pImpl is not accessible from static boost::log::v2_mt_posix::attribute_value_set::implementation::create( boost::rv<boost::log::v2_mt_posix::attribute_value_set>&, const boost::log::v2_mt_posix::attribute_set&, const boost::log::v2_mt_posix::attribute_set&, unsigned ).

The same error happens on line 214 as well.

Here's the code in question:

/* ... */
static implementation* create(
    BOOST_RV_REF(attribute_value_set) source_attrs,
    attribute_set const& thread_attrs,
    attribute_set consyt& global_attrs,
    size_type reserve_count)
{
->  implementation* p = source_attrs.m_pImpl;
->  source_attrs.m_pImpl = NULL;
    p->m_pThreadAttributes = thread_attrs.m_pImpl;
    p->m_pGlobalAttributes = global_attrs.m_pImpl;
    return p;
}

In boost/log/attributes/attribute_value_set.hpp, on or about line 97, the private struct implementation is pre-declared but is not marked as a friend. In the body for attribute_value_set::implementation::create( ::boost::rv<attribute_value_set>&, /* ... */ ) (on or about line 208 in attribute_value_set.cpp), the compiler complains that m_pImpl is not accessible.

This is not reproducible on gcc (3.4.6 and 4.4.6) or clang. If the header for attribute_value_set is modified to make implementation a friend class, the problem goes away.

The following is a piece of example code that exemplifies the problematic idiom; again, this [so far] is only reproducible in Sun Studio:

// represents 'boost::rv'
template <class T>
class A : public T {
};

// represents 'class attribute_value_set'
class B {
  // represents 'struct implementation'
  struct BS {
    static void blah( A<B>&b, int y ) {
      b.x = y;
    }
  };

  int x;

public:
  B() : x(0) {}
  void stuff( int y ) {
    BS::blah( *this, y );
  }

  operator A<B>& () {
    return *static_cast< A<B>* >( this );
  }
};

int main( int argc, char *argv[] ) {
  B b;

  b.stuff( 3 );

  return 0;
}

Change History (2)

comment:1 by Brian Vandenberg <phantall+boost@…>, 9 years ago

Cc: phantall+boost@… added

comment:2 by Andrey Semashev, 9 years ago

Resolution: fixed
Status: newclosed

(In [85871]) Fixed #9139.

Note: See TracTickets for help on using tickets.