Bug 1542187

Summary: boost.format compilation fails with gcc-8.0.1
Product: [Fedora] Fedora Reporter: Jaroslav Škarvada <jskarvad>
Component: gccAssignee: Jonathan Wakely <jwakely>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 28CC: aoliva, dakingun, davejohansen, denis.arnaud_fedora, fweimer, jakub, jwakely, law, me, mpolacek
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-04-30 21:10:59 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:
Attachments:
Description Flags
Reproducer none

Description Jaroslav Škarvada 2018-02-05 19:12:37 UTC
Created attachment 1391688 [details]
Reproducer

Description of problem:
Attached is a stripped down reproducer from the uhd package which fails to compile with gcc-8.0.1-0.9, but compiles with the gcc-7.2.1-2.

Version-Release number of selected component (if applicable):
gcc-8.0.1-0.9.fc28.x86_64
boost-1.66.0-0.1.fc26.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Compile attached reproducer
2.
3.

Actual results:
test2.c: In instantiation of ‘double max287x<max287x_regs_t>::set_frequency(double, bool) [with max287x_regs_t = max2871_regs_t]’:
test2.c:28:41:   required from here
test2.c:19:56: error: cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
   std::cout << boost::format("MAX287x: tune: type=%s") % ((is_int_n) ? "Integer-N" : "Fractional") << std::endl;
In file included from /usr/include/boost/format.hpp:41,
                 from test2.c:2:
/usr/include/boost/format/format_class.hpp:67:44: note:   initializing argument 1 of ‘boost::basic_format<Ch, Tr, Alloc>& boost::basic_format<Ch, Tr, Alloc>::operator%(T&) [with T = const char*; Ch = char; Tr = std::char_traits<char>; Alloc = std::allocator<char>]’
         template<class T>  basic_format&   operator%(T& x)
                                            ^~~~~~~~

Expected results:
No error

Additional info:
I cannot see what's wrong with the code, it seems OK to me.

The following workaround seems to make it compile again:
-  std::cout << boost::format("MAX287x: tune: type=%s") % ((is_int_n) ? "Integer-N" : "Fractional") << std::endl;
+  std::cout << boost::format("MAX287x: tune: type=%s") % ((is_int_n) ? std::string("Integer-N") : std::string("Fractional")) << std::endl;

Comment 1 Jonathan Wakely 2018-02-06 12:48:15 UTC
This doesn't seem like a Boost (In reply to Jaroslav Škarvada from comment #0)
> Description of problem:
> Attached is a stripped down reproducer from the uhd package which fails to
> compile with gcc-8.0.1-0.9, but compiles with the gcc-7.2.1-2.

This is a GCC bug not a Boost bug, you get the same error for gcc-8 on f26 with boost-1.64.0


struct format {
  template<typename T> format& operator%(const T&) { return *this; }
  template<typename T> format& operator%(T&) { return *this; }
};

format f;

template <typename>
void function_template(bool b)
{
  // Compiles OK with array lvalue:
  f % (b ? "x" : "x");

  // Fails with pointer rvalue:
  f % (b ? "" : "x");
}

void normal_function(bool b)
{
  // Both cases compile OK in non-template function:
  f % (b ? "x" : "x");
  f % (b ? "" : "x");

  function_template<void>(b);
}

Comment 2 Jonathan Wakely 2018-02-06 12:53:30 UTC
Reported upstream.

Comment 3 Jonathan Wakely 2018-02-06 21:25:54 UTC
(In reply to Jaroslav Škarvada from comment #0)
> The following workaround seems to make it compile again:
> -  std::cout << boost::format("MAX287x: tune: type=%s") % ((is_int_n) ?
> "Integer-N" : "Fractional") << std::endl;
> +  std::cout << boost::format("MAX287x: tune: type=%s") % ((is_int_n) ?
> std::string("Integer-N") : std::string("Fractional")) << std::endl;

A better workaround is:

 std::cout << boost::format("MAX287x: tune: type=%s") %
   (const char*)((is_int_n) ? "Integer-N" : "Fractional") << std::endl;

i.e. cast the conditional expression to const char* (which is the type it has anyway, but this avoids the GCC bug).

Comment 4 Fedora End Of Life 2018-02-20 15:38:55 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 28 development cycle.
Changing version to '28'.

Comment 5 Marek Polacek 2018-04-30 21:10:59 UTC
Should be already fixed.