Bug 1482990 - glibc-2.26-2.fc27 breaks assert on C++ objects: no match for 'operator=='
Summary: glibc-2.26-2.fc27 breaks assert on C++ objects: no match for 'operator=='
Keywords:
Status: CLOSED NEXTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: ccgo
Version: 27
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Petr Pisar
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-08-18 14:19 UTC by Petr Pisar
Modified: 2017-08-22 09:23 UTC (History)
11 users (show)

Fixed In Version: ccgo-0.3.6.5-7.fc27
Clone Of:
: 1483005 (view as bug list)
Environment:
Last Closed: 2017-08-18 15:17:41 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Sourceware 21242 0 P2 RESOLVED assert gives pedantic warning in old gcc versions 2021-01-28 11:24:27 UTC

Description Petr Pisar 2017-08-18 14:19:42 UTC
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))?

Comment 1 Florian Weimer 2017-08-18 14:31:46 UTC
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);

Comment 2 Petr Pisar 2017-08-18 14:48:16 UTC
Thanks for the explanation. That makes sense.

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

Comment 3 Florian Weimer 2017-08-18 14:55:04 UTC
We are still going to fix this in glibc, so I'm going to clone this bug.

Comment 4 Jonathan Wakely 2017-08-18 19:31:09 UTC
(In reply to Petr Pisar from comment #2)
> I also found assert(NULL!=a) not working on Glib::RefPtr objects. The
> assert(!!a) is better.

Or assert(static_cast<bool>(a))

A library issue has been opened requesting clarification in the C++ standard:
https://cplusplus.github.io/LWG/issue3011

My suggestion is that C++ adds explicit wording to repeat the C standard's requirement that the condition should have scalar type. So assert((bool)a) and assert(!!a) would be OK, but assert(a) would not.

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


Note You need to log in before you can comment on or make changes to this bug.