Using C++11 <atomic> with Clang SVN

I am having trouble with <atomic> and Clang SVN (Mac OSX Lion). Here is
the test program:

    #include <atomic>

    int main()
    {
        std::atomic_size_t a(0ul);
        ++a;
        --a;

        return 0;
    }

This generates the following error:

    In file included from test.cc:1:
    /usr/include/c++/v1/atomic:1352:51: error: too few arguments to
function call, expected 4, have 3
            {return __atomic_exchange(&__a_, true, __m);}
                    ~~~~~~~~~~~~~~~~~ ^
    /usr/include/c++/v1/atomic:1355:51: error: too few arguments to
function call, expected 4, have 3
            {return __atomic_exchange(&__a_, true, __m);}
                    ~~~~~~~~~~~~~~~~~ ^

From the C++11 status page [1], I see that atomic operations (N2427) are

already supported in the SVN repository, but strong compare and exchange
(N2748) not yet. Is the above error message occurring due to the lacking
support for N2748?

    Matthias

[1] http://clang.llvm.org/cxx_status.html

Make sure you check out libc++ into llvm/projects/libcxx/, and use
"make install", so clang uses the right libcxx.

We should probably update the "Getting Started" instructions to mention that...

-Eli

Make sure you check out libc++ into llvm/projects/libcxx/, and use
"make install", so clang uses the right libcxx.

I tried to check out libc++ into llvm/projects/libcxx and invoking
configure again. This message during configure gives me pause though:

    configure: WARNING: Unknown project (libcxx) won't be configured
automatically

Even passing --enable-libcpp to configure does not get rid of this
warning. In fact, the Makefile in llvm/projects mentions:

    # Don't build libcxx, it isn't designed to be built directly.
    DIRS := $(filter-out libcxx,$(DIRS))

Should clang pick up libc++ automatically or am I supposed to install it
manually first?

    Matthias

The Makefile that actually does the relevant stuff is in
clang/runtime/libcxx/. You shouldn't need to install libc++
separately.

-Eli

No, it results from your libc++ not being new enough.

We do not claim that strong compare-exchange is listed as supported because the strong/weak distinction is not available in LLVM IR (we always generate a strong compare-exchange). Maybe we should just mark it as done to avoid confusion.

+1 – the requirement should be for support of strong, not for differentiation between strong and weak IMO…

Marking more C++11 boxes as done is fine by me! In r155161.

I was holding back from doing this before because the purpose of N2748 was to get better code for weak compare exchanges, which we don’t actually do. That said, I have no idea if we support architectures for which there is a more efficient weak compare-exchange available.

My thought when designing this was that
1) It may well be possible for the backend to optimize strong cmpxchg
into weak cmpxchg in many of the important use cases. Someone should
try that before adding a new LLVM instruction.
2) The companies that develop or use architectures with a weak cmpxchg
(ARM, PPC, at least) can contribute the optimization when it matters
to them. Until then, it's simpler to have only one variant.

Jeffrey

The Makefile that actually does the relevant stuff is in
clang/runtime/libcxx/. You shouldn't need to install libc++
separately.

Thanks, the examples now compiles fine with the new libc++.

    Matthias

Wow, that actually works on some OS (macosx only I guess)? It seems so far here...

- requires root (chown)
- doesn't compile the lib
- installs the include files in a place the driver doesn't know
- fixed path in the driver
etc.

Make sure you check out libc++ into llvm/projects/libcxx/, and use
"make install", so clang uses the right libcxx.

Wow, that actually works on some OS (macosx only I guess)? It seems so far
here...

- requires root (chown)

Yes, that's slightly less than ideal.

- doesn't compile the lib

Not necessary on OS X Lion.

- installs the include files in a place the driver doesn't know

I'm not sure I follow here... at least on Mac, we search for libcxx
relative to the clang executable.

-Eli

Make sure you check out libc++ into llvm/projects/libcxx/, and use
"make install", so clang uses the right libcxx.

Wow, that actually works on some OS (macosx only I guess)? It seems so far
here...

- requires root (chown)

Yes, that's slightly less than ideal.

- doesn't compile the lib

Not necessary on OS X Lion.

Uh? I'd understand if you said the makefile compiles it on OSX but not on other platforms. But saying that it isn't necessary because the system provides an older version seems strange.

- installs the include files in a place the driver doesn't know

I'm not sure I follow here... at least on Mac, we search for libcxx
relative to the clang executable.

Ok, good to know that it works on Mac, thanks. On Linux, the headers get installed in $INST/lib/c++/v1, but the driver looks for them in:

     // libc++ is always installed at a fixed path on Linux currently.
     addSystemInclude(DriverArgs, CC1Args,
                      getDriver().SysRoot + "/usr/include/c++/v1");

Make sure you check out libc++ into llvm/projects/libcxx/, and use
"make install", so clang uses the right libcxx.

Wow, that actually works on some OS (macosx only I guess)? It seems so far
here...

- requires root (chown)

Yes, that's slightly less than ideal.

- doesn't compile the lib

Not necessary on OS X Lion.

Uh? I'd understand if you said the makefile compiles it on OSX but not on
other platforms. But saying that it isn't necessary because the system
provides an older version seems strange.

The system provides a stable version of the library that works with updated headers.

- installs the include files in a place the driver doesn't know

I'm not sure I follow here... at least on Mac, we search for libcxx
relative to the clang executable.

Ok, good to know that it works on Mac, thanks. On Linux, the headers get
installed in $INST/lib/c++/v1, but the driver looks for them in:

    // libc++ is always installed at a fixed path on Linux currently.
    addSystemInclude(DriverArgs, CC1Args,
                     getDriver().SysRoot + "/usr/include/c++/v1");

Clang should probably always look for them in $INST/lib/c++/v1, on all platforms, but nobody has taken the initiative to make Clang + libc++ distribution clean on non-Mac platforms.

  - Doug