...
OK I attached a new test case - 27.basic_ios.copyfmt.stdcxx-1058.cpp.

But, using a simple derived class from std::basic_ios doesn't trigger
the bug. It's only triggered when using std::fstream or
std::stringstream.

Here's what I meant:

  struct A: std::streambuf { };
  struct B: std::ios {
    A sb;
    B () { init (&sb); }
  } f0, f1;

Btw., in your new test, either the TEST_ASSERT() macro should abort
or the test should when before returning ret is non-zero.

I.e., every regression test should report failure by calling abort
(via the assert() macro).

Returning a non-zero exit status (in addition to making use of
assert()) is fine but it shouldn't be the sole mechanism for
reporting an error.

Also, please avoid #including <iostream> in tests unless
exercising the standard streams (std::cout et al.) The header
runs complicated code and can lead to unrelated failures.

Attached is a slightly modified test to show what I mean. (Also
fixes formatting -- please use 4 space indents and a space before
each open paren; curly brace goes on the same line as the statement
except for namespace scope declarations).

Martin


--Stefan


/**************************************************************************
 *
 * 27.ios_base.event_callback.stdcxx-1058.cpp - regression test for STDCXX-1058
 *
 * http://issues.apache.org/jira/browse/STDCXX-1058
 *
 * $Id$
 *
 **************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 **************************************************************************/
/*
 * This program should run to completion and exit with return status 0
 */

#include <cassert>
#include <ios>
#include <cstdio>

#define TEST_ASSERT(expr)                                               \
    (expr) ? ret = 0                                                    \
        : std::fprintf (stderr,"line %i: Assertion failed: %s\n",       \
                        __LINE__, #expr)

int x;

void testfun (std::ios_base::event ev, std::ios_base& iosobj, int index)
{
    x = index;

    switch (ev) {
    case std::ios_base::copyfmt_event:
        std::fprintf (stderr, "copyfmt_event\n");
        break;
    case std::ios_base::imbue_event:
        std::fprintf (stderr, "imbue_event\n");
        break;
    case std::ios_base::erase_event:
        std::fprintf (stderr, "erase_event\n");
        break;
    default:
       std::fprintf (stderr, "unknown (this should never happen)\n");
       break;
    }
}


int main ()
{
    struct A: std::streambuf { };
    struct B: std::ios {
        A sb;
        B () { init (&sb); }
    } f0, f1;

    int i = 101;
    int ret = 1;

    std::ios_base::event_callback e1 = &testfun;
    f0.register_callback (e1, i);

    x = 0;
    f0.imbue (f0.getloc ());
    TEST_ASSERT (x == i);

    x = 0;
    f0.copyfmt (f1);
    TEST_ASSERT (x == i);

    B s0, s1;

    s0.register_callback (e1, i);

    x = 0;
    s0.imbue (f0.getloc ());
    TEST_ASSERT (x == i);

    x = 0;
    s0.copyfmt (s1);
    TEST_ASSERT (x == i);

    assert (ret == 0);

    return ret;
}

Reply via email to