Bug 216404

Summary: graphics/GraphicsMagick: fails to build with libc++ 4.0 (110 ports skipped)
Product: Ports & Packages Reporter: Jan Beich <jbeich>
Component: Individual Port(s)Assignee: Po-Chuan Hsieh <sunpoet>
Status: Closed FIXED    
Severity: Affects Only Me CC: dim, eric
Priority: --- Keywords: needs-patch
Version: LatestFlags: bugzilla: maintainer-feedback? (sunpoet)
Hardware: Any   
OS: Any   
Bug Depends on:    
Bug Blocks: 216008    

Description Jan Beich freebsd_committer freebsd_triage 2017-01-23 11:54:21 UTC
The port defines USES=compiler:gcc-c++11-lib to build with OpenMP support via GCC 4.9 (C++98 by default) since LLVM libomp is broken on most architectures FreeBSD supports (i386, aarch64, armv6, powerpc*).

checking whether the compiler supports ISO C++ standard library... no
checking whether the compiler supports ios::binary... no
checking whether C++ compiler is sufficient for Magick++... no (failed tests)
[...]
Magick++          --with-magick-plus-plus=yes  no (failed tests)
[...]
=======================<phase: package        >============================
===>  Building package for GraphicsMagick-1.3.25_1,1
pkg-static: Unable to access file /wrkdirs/usr/ports/graphics/GraphicsMagick/work/stage/usr/local/bin/GraphicsMagick++-config: No such file or directory
pkg-static: Unable to access file /wrkdirs/usr/ports/graphics/GraphicsMagick/work/stage/usr/local/include/GraphicsMagick/Magick++.h: No such file or directory
pkg-static: Unable to access file /wrkdirs/usr/ports/graphics/GraphicsMagick/work/stage/usr/local/include/GraphicsMagick/Magick++/Blob.h: No such file or directory
pkg-static: Unable to access file /wrkdirs/usr/ports/graphics/GraphicsMagick/work/stage/usr/local/include/GraphicsMagick/Magick++/CoderInfo.h: No such file or directory
pkg-static: Unable to access file /wrkdirs/usr/ports/graphics/GraphicsMagick/work/stage/usr/local/include/GraphicsMagick/Magick++/Color.h: No such file or directory
[...]

build log: http://sprunge.us/MJaP
regressed by: https://github.com/llvm-mirror/libcxx/commit/120401a4e033

$ pkg install gcc

$ cat >a.cc
#include <iostream>
using namespace std;
int main(void) { return 0; }

$ g++49 -nostdinc++ -isystem /usr/include/c++/v1 -c a.cc
In file included from /usr/include/c++/v1/__locale:15:0,
                 from /usr/include/c++/v1/ios:216,
                 from /usr/include/c++/v1/iostream:38,
                 from a.cc:1:
/usr/include/c++/v1/string:823:45: error: default template arguments may not be used in function templates without -std=c++11 or -std=gnu++11
     basic_string& operator=(__self_view __sv)  {return assign(__sv);}
                                             ^
Comment 1 Jan Beich freebsd_committer freebsd_triage 2017-01-23 12:01:02 UTC
(In reply to Jan Beich (mail not working) from comment #0)
> regressed by: https://github.com/llvm-mirror/libcxx/commit/120401a4e033

Oops, that was a different issue. Here's the first bad for comment 0:

https://github.com/llvm-mirror/libcxx/commit/39c36254e556
Comment 2 Dimitry Andric freebsd_committer freebsd_triage 2017-01-23 20:29:42 UTC
(In reply to Jan Beich (mail not working) from comment #1)
> (In reply to Jan Beich (mail not working) from comment #0)
> > regressed by: https://github.com/llvm-mirror/libcxx/commit/120401a4e033
> 
> Oops, that was a different issue. Here's the first bad for comment 0:
> 
> https://github.com/llvm-mirror/libcxx/commit/39c36254e556

Yes, I replied to Eric on that commit on the cfe-commits mailing list.  It would be nice if there is a fallback for pre-C++11.  Basically omitting the "template <class = void>" line for it would be enough, I think.

Although, the simple test case from that commit:

#include <string>
#include <cassert>

int main()
{
  // Test that assignment from {} and {ptr, len} are allowed and are not
  // ambiguous.
  {
    std::string s = "hello world";
    s = {};
    assert(s.empty());
  }
  {
    std::string s = "hello world";
    s = {"abc", 2};
    assert(s == "ab");
  }
  return 0;
}

will not compile with g++ (4.9 or 5.4) in pre-C++11 mode, because of an ambiguity:

$ g++5 -nostdinc++ -I/usr/include/c++/v1 -c test.cpp
test.cpp: In function 'int main()':
test.cpp:10:10: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {};
          ^
test.cpp:10:7: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {};
       ^
test.cpp:10:7: error: ambiguous overload for 'operator=' (operand types are 'std::__1::string {aka std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >}' and '<brace-enclosed initializer list ')
In file included from test.cpp:1:0:
/usr/include/c++/v1/string:2007:1: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(const std::__1::basic_string<_CharT, _Traits, _Allocator>&) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>]
 basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
 ^
/usr/include/c++/v1/string:825:19: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(std::__1::basic_string<_CharT, _Traits, _Allocator>::__self_view) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>; std::__1::basic_string<_CharT, _Traits, _Allocator>::__self_view = std::__1::basic_string_view<char>]
     basic_string& operator=(__self_view __sv)  {return assign(__sv);}
                   ^
/usr/include/c++/v1/string:831:45: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(const value_type*) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>; std::__1::basic_string<_CharT, _Traits, _Allocator>::value_type = char]
     _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
                                             ^
/usr/include/c++/v1/string:1986:1: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(std::__1::basic_string<_CharT, _Traits, _Allocator>::value_type) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>; std::__1::basic_string<_CharT, _Traits, _Allocator>::value_type = char]
 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
 ^
/usr/include/c++/v1/string:835:19: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(std::initializer_list<typename _Traits::char_type>) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>; typename _Traits::char_type = char]
     basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
                   ^
test.cpp:15:18: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {"abc", 2};
                  ^
test.cpp:15:7: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {"abc", 2};
       ^
test.cpp:15:7: error: ambiguous overload for 'operator=' (operand types are 'std::__1::string {aka std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >}' and '<brace-enclosed initializer list ')
In file included from test.cpp:1:0:
/usr/include/c++/v1/string:2007:1: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(const std::__1::basic_string<_CharT, _Traits, _Allocator>&) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>]
 basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
 ^
/usr/include/c++/v1/string:825:19: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(std::__1::basic_string<_CharT, _Traits, _Allocator>::__self_view) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>; std::__1::basic_string<_CharT, _Traits, _Allocator>::__self_view = std::__1::basic_string_view<char>]
     basic_string& operator=(__self_view __sv)  {return assign(__sv);}
                   ^
/usr/include/c++/v1/string:835:19: note: candidate: std::__1::basic_string<_CharT, _Traits, _Allocator>& std::__1::basic_string<_CharT, _Traits, _Allocator>::operator=(std::initializer_list<typename _Traits::char_type>) [with _CharT = char; _Traits = std::__1::char_traits<char>; _Allocator = std::__1::allocator<char>; typename _Traits::char_type = char]
     basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
                   ^

On the other hand, it also does not compile when you use its own libstdc++, in that case:

$ g++5 -c test.cpp
test.cpp: In function 'int main()':
test.cpp:10:10: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {};
          ^
test.cpp:10:7: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {};
       ^
test.cpp:10:7: error: ambiguous overload for 'operator=' (operand types are 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' and '<brace-enclosed initializer list>')
In file included from /usr/local/lib/gcc5/include/c++/string:52:0,
                 from test.cpp:1:
/usr/local/lib/gcc5/include/c++/bits/basic_string.h:550:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator=(const basic_string& __str)
       ^
/usr/local/lib/gcc5/include/c++/bits/basic_string.h:558:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator=(const _CharT* __s)
       ^
/usr/local/lib/gcc5/include/c++/bits/basic_string.h:569:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator=(_CharT __c)
       ^
test.cpp:15:18: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {"abc", 2};
                  ^
test.cpp:15:7: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     s = {"abc", 2};
       ^
Comment 3 commit-hook freebsd_committer freebsd_triage 2017-01-23 22:11:31 UTC
A commit references this bug:

Author: dim
Date: Mon Jan 23 22:10:57 UTC 2017
New revision: 312673
URL: https://svnweb.freebsd.org/changeset/base/312673

Log:
  Pull in r292830 from upstream libc++ trunk (by Eric Fiselier):

    Fix GCC C++03 build by hiding default template argument in C++03

  This allows the graphics/GraphicsMagic to compile with gcc 4.9 and
  libc++.

  PR:		216404

Changes:
  projects/clang400-import/contrib/libc++/include/string
Comment 4 Dimitry Andric freebsd_committer freebsd_triage 2017-01-29 16:31:33 UTC
Should be fixed now, after r312673.