Bug 216054

Summary: graphics/openshadinglanguage: fails to build with libc++ 4.0
Product: Ports & Packages Reporter: Jan Beich <jbeich>
Component: Individual Port(s)Assignee: Dimitry Andric <dim>
Status: Closed FIXED    
Severity: Affects Only Me CC: FreeBSD, dim, eric
Priority: --- Keywords: needs-patch
Version: Latest   
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=216010
Bug Depends on:    
Bug Blocks: 216008    
Attachments:
Description Flags
graphics/openshadinglanguage update none

Description Jan Beich freebsd_committer freebsd_triage 2017-01-14 05:57:54 UTC
In file included from llvm_ops.cpp:94:
In file included from /usr/include/c++/v1/iostream:38:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
In file included from /usr/include/c++/v1/string:470:
In file included from /usr/include/c++/v1/string_view:171:
In file included from /usr/include/c++/v1/__string:55:
In file included from /usr/include/c++/v1/algorithm:637:
/usr/include/c++/v1/type_traits:2075:14: error: expected class name
    : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {};
             ^
/usr/include/c++/v1/__config:738:25: note: expanded from macro 'decltype'
#  define decltype(__x) __typeof__(__x)
                        ^

build log: http://sprunge.us/Zjhh
regressed by: https://github.com/llvm-mirror/libcxx/commit/602fe15f55ea
Comment 1 Jan Beich freebsd_committer freebsd_triage 2017-01-18 17:00:27 UTC
libc++ 4.0 is just broken with old compilers. One workaround would be to build against devel/libc++ which tracks old version.

$ cat a.cc
#include <string>

int main() { return 0; }

$ clang++34 a.cc
In file included from a.cc:1:
In file included from /usr/include/c++/v1/string:470:
In file included from /usr/include/c++/v1/string_view:171:
In file included from /usr/include/c++/v1/__string:56:
In file included from /usr/include/c++/v1/algorithm:637:
/usr/include/c++/v1/type_traits:2075:14: error: expected class name
    : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {};
             ^
/usr/include/c++/v1/__config:747:25: note: expanded from macro 'decltype'
#  define decltype(__x) __typeof__(__x)
                        ^
1 error generated.
Comment 2 Shane 2017-01-22 15:05:40 UTC
Created attachment 179215 [details]
graphics/openshadinglanguage update

I had meant to update this a while back, was expecting another release to be tagged by now.

-Update to 1.7.5
-Add indirect dependencies
-Remove clang34 from BUILD_DEPENDS
-Remove USES=compiler - was to prevent use of gcc42
-Remove 9.x specific adjustment (flex BUILD_DEPENDS)
-Disable USE_LLVM_BITCODE on 12-current - this prevents the use of llvm-as which fails after the import of clang 4.0 into base.
Comment 3 Dimitry Andric freebsd_committer freebsd_triage 2017-01-22 19:26:25 UTC
(In reply to Jan Beich (mail not working) from comment #1)
> libc++ 4.0 is just broken with old compilers. One workaround would be to
> build against devel/libc++ which tracks old version.
> 
> $ cat a.cc
> #include <string>
> 
> int main() { return 0; }
> 
> $ clang++34 a.cc
> In file included from a.cc:1:
> In file included from /usr/include/c++/v1/string:470:
> In file included from /usr/include/c++/v1/string_view:171:
> In file included from /usr/include/c++/v1/__string:56:
> In file included from /usr/include/c++/v1/algorithm:637:
> /usr/include/c++/v1/type_traits:2075:14: error: expected class name
>     : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {};
>              ^
> /usr/include/c++/v1/__config:747:25: note: expanded from macro 'decltype'
> #  define decltype(__x) __typeof__(__x)
>                         ^
> 1 error generated.

Hm, yes that is pretty unfortunate.  Not that you can guarantee forwards compatibility forever, of course, but in this case it falls over a C++11 construct, while in C++98 (or GNU++98) mode.

It looks like before libc++ r276599, there was a fallback mode for _LIBCPP_HAS_NO_RVALUE_REFERENCES, but that disappeared.  Eric, how tricky would it be to put that back?
Comment 4 Eric Fiselier 2017-01-23 21:13:21 UTC
Clang 3.4 provides the `__decltype` keyword, but it doesn't provide the `__is_identifier` check that libc++ uses to detect it.

As long as you don't use anything less that Clang 3.4 you could upstream a patch that just always enabled `__decltype` instead of `__typeof__` and it should work.
Comment 5 Dimitry Andric freebsd_committer freebsd_triage 2017-01-23 21:23:28 UTC
(In reply to Dimitry Andric from comment #3)
> (In reply to Jan Beich (mail not working) from comment #1)
> > libc++ 4.0 is just broken with old compilers. One workaround would be to
> > build against devel/libc++ which tracks old version.

Now that I think about it, how did you end up with clang 3.4 in this build?  It looks like clang 3.5 through 4.0 all accept <string.h> from libc++ 4.0, even if you explicitly specify -std=c++98.
Comment 6 Jan Beich freebsd_committer freebsd_triage 2017-01-23 21:38:15 UTC
(In reply to Eric Fiselier from comment #4)
> As long as you don't use anything less that Clang 3.4 you could upstream a
> patch that just always enabled `__decltype` instead of `__typeof__` and it
> should work.

We have 3 ports that depend on Clang 3.3 but unconditionally using __decltype in libc++'s __config works fine, at least with comment 1 test.

(In reply to Dimitry Andric from comment #5)
Via llvm-config34 --prefix, see src/liboslexec/CMakeLists.txt:

    # Figure out what program we will use to make the bitcode.
    if (NOT LLVM_BC_GENERATOR)
        FIND_PROGRAM(LLVM_BC_GENERATOR NAMES "clang++" PATHS "${LLVM_DIRECTORY}/bin" NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH)
    endif ()
Comment 7 Eric Fiselier 2017-01-23 21:41:01 UTC
I'm going to try and upstream fix that forces libc++ to use `__decltype` in Clang 3.4 so should shouldn't have to carry a patch downstream.
Comment 8 Jan Beich freebsd_committer freebsd_triage 2017-01-23 23:17:38 UTC
(In reply to Eric Fiselier from comment #7)
> upstream fix that forces libc++ to use `__decltype` in Clang 3.4

Not sure why libc++ pretends the burned __typeof__ bridge would still work rather than clean up. However, lang/clang33 consumers in the ports tree are unaffected: either build with -std=c++11 or only use libclang.

I confirm, after applying libc++ r292833 graphics/openshadinglanguage builds fine: http://sprunge.us/WOOE
Comment 9 commit-hook freebsd_committer freebsd_triage 2017-01-23 23:20:45 UTC
A commit references this bug:

Author: dim
Date: Mon Jan 23 23:20:01 UTC 2017
New revision: 312675
URL: https://svnweb.freebsd.org/changeset/base/312675

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

    Manually force the use of __decltype in C++03 with Clang 3.4.

    <string> uses `decltype` in a way incompatible with `__typeof__`.
    This is problematic when compiling <string> with Clang 3.4 because
    even though it provides `__decltype` libc++ still used `__typeof__`
    because clang 3.4 doesn't provide __is_identifier which libc++
    uses to detect __decltype.

    This patch manually detects Clang 3.4 and properly configures
    for it.

  This allows the graphics/openshadinglanguage port to build with
  lang/clang34.

  PR:		216054

Changes:
  projects/clang400-import/contrib/libc++/include/__config
Comment 10 Jan Beich freebsd_committer freebsd_triage 2017-01-23 23:38:43 UTC
Comment on attachment 179215 [details]
graphics/openshadinglanguage update

Can you file a new bug, attach a version without libc++ 4.0 hack and CC me? AFAIK, GCC 4.2 is still supported on mips*, sparc64, powerpc*.