Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.

Bug 1483005

Summary: glibc-2.26-2.fc27 breaks assert on C++ objects: no match for 'operator=='
Product: [Fedora] Fedora Reporter: Florian Weimer <fweimer>
Component: glibcAssignee: Florian Weimer <fweimer>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 27CC: arjun.is, avi.kivity, codonell, dj, extras-qa, fweimer, jan.kratochvil, law, mfabian, pfrankli, ppisar, sbergman, siddhesh
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: glibc-2.26.90-6.fc28 glibc-2.26-4.fc27 glibc-2.25-9.fc26 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: 1482990 Environment:
Last Closed: 2017-10-07 11:02:07 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Florian Weimer 2017-08-18 14:55:54 UTC
+++ This bug was initially created as a clone of Bug #1482990 +++

Koschei reports build failures on C++ packages since glibc-2.26-2.fc27 like this in ccgo package:

g++ -DHAVE_CONFIG_H -I. -I..  -I/usr/include/gtkmm-2.4 -I/usr/lib64/gtkmm-2.4/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-2.0 -I/usr/lib64/gtk-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gtk-unix-print-2.0 -I/usr/include/gdkmm-2.4 -I/usr/lib64/gdkmm-2.4/include -I/usr/include/gconfmm-2.6 -I/usr/lib64/gconfmm-2.6/include -I/usr/include/gconf/2 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -pthread    -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic -c -o gmap.o gmap.cc
In file included from /usr/include/c++/7/cassert:44:0,
                 from ../debug.hh:27,
                 from gtk.cc:24:
gtk.cc: In member function 'virtual void gtk::View::do_geom()':
gtk.cc:488:4: error: no match for 'operator==' (operand types are 'Glib::RefPtr<Gtk::Action>' and 'int')
    assert(a);
    ^
gtk.cc:488:4: note: candidate: operator==(int, int) <built-in>
gtk.cc:488:4: note:   no known conversion for argument 1 from 'Glib::RefPtr<Gtk::Action>' to 'int'

The code C++ is:

void View::do_geom()
{
    set_max_depth();
    set_alternative();
    switch (mode) {
    case MODE_INIT:
        if (! game_can_init()) {
            Glib::RefPtr<Gtk::Action> a = m_uim->get_action(act_name[persist_mode]);
→           assert(a);
            a->activate();
        }
        break;
    [...]
    }
[...]
}

Affected packages:
ccgo <https://apps.fedoraproject.org/koschei/build/3229493>
filezilla <https://apps.fedoraproject.org/koschei/build/3225767>

I believe it's triggered with this glibc-2.26-2 change:

- assert: Suppress pedantic warning caused by statement expression (swbz#21242)

From the upstream commit <https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2aa1a7a8f8b9b7879bc6eb1c34d1580f992c406d;hp=c55ad6452e2d63ebf6fcaabb00bfd27aae02ffb6>:

--- a/assert/assert.h
+++ b/assert/assert.h
@@ -91,13 +91,19 @@ __END_DECLS
      ? __ASSERT_VOID_CAST (0)                                          \
      : __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
 # else
+/* The first occurrence of EXPR is not evaluated due to the sizeof,
+   but will trigger any pedantic warnings masked by the __extension__
+   for the second occurrence.  The explicit comparison against zero is
+   required to support function pointers and bit fields in this
+   context, and to suppress the evaluation of variable length
+   arrays.  */
 #  define assert(expr)                                                 \
-    ({                                                                 \
+  ((void) sizeof ((expr) == 0), __extension__ ({                       \
       if (expr)                                                                \
         ; /* empty */                                                  \
       else                                                             \
         __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION);  \
-    })
+    }))
 # endif

Is this a glibc bug or the C++ application bug (like assert(NULL!=a))?

--- Additional comment from Florian Weimer on 2017-08-18 16:31:46 CEST ---

The C++ standard incorporates the C standard, which requires a comparison against 0:

“
The assert macro puts diagnostic tests into programs; it expands to a void expression.  When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed […]
”

This is arguably a defect in the C++ standard because it also talks about “contextually converted to bool”, but it is how things stand today: you need a valid operator== for comparison with int to use the assert macro.

You can probably use this:

  assert(!!a);

--- Additional comment from Petr Pisar on 2017-08-18 16:48:16 CEST ---

Thanks for the explanation. That makes sense.

I also found assert(NULL!=a) not working on Glib::RefPtr objects. The assert(!!a) is better.

--- Additional comment from Florian Weimer on 2017-08-18 16:55:04 CEST ---

We are still going to fix this in glibc, so I'm going to clone this bug.

Comment 1 Stephan Bergmann 2017-08-21 15:40:25 UTC
> You can probably use this:
> 
>   assert(!!a);

But operator! can be overloaded for the type of a, so that's not guaranteed to work, either.  I think the only way to make that work is to split the assert macro for __cplusplus and have

  (void) sizeof bool(expr)

there.

Comment 2 Avi Kivity 2017-08-21 22:04:28 UTC
Note Fedora 26 (and its users) suffer from the same problem.

Comment 3 Florian Weimer 2017-08-22 06:26:34 UTC
*** Bug 1483821 has been marked as a duplicate of this bug. ***

Comment 4 Fedora Update System 2017-08-22 09:23:35 UTC
glibc-2.25-9.fc26 has been submitted as an update to Fedora 26. https://bodhi.fedoraproject.org/updates/FEDORA-2017-781951efb3

Comment 5 Fedora Update System 2017-08-23 09:04:01 UTC
glibc-2.25-9.fc26 has been pushed to the Fedora 26 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2017-781951efb3

Comment 6 Fedora Update System 2017-08-23 19:55:15 UTC
glibc-2.25-9.fc26 has been pushed to the Fedora 26 stable repository. If problems still persist, please make note of it in this bug report.