forked from llvm-mirror/clang
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ugly ugly hack for libstdc++-4.6 and libstdc++-4.7 compatibility. These
libraries have an incorrect definition of std::common_type (inherited from a bug in the standard -- see LWG issue 2141), whereby they produce reference types when they should not. If we instantiate a typedef named std::common_type<...>::type, which is defined in a system header as decltype(... ? ... : ...), and the decltype produces a reference type, convert it to the non-reference type. (This doesn't affect any LWG2141-conforming implementation of common_type, such as libc++'s, because the default implementation of common_type<...>::type isn't supposed to produce a reference type.) This is horrible. I'm really sorry. :( Better ideas appreciated! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166455 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
3 changed files
with
53 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify | ||
|
||
// This is a test for an egregious hack in Clang that works around | ||
// an issue with GCC's <type_traits> implementation. std::common_type | ||
// relies on pre-standard rules for decltype(), in which it doesn't | ||
// produce reference types so frequently. | ||
|
||
#ifdef BE_THE_HEADER | ||
|
||
#pragma GCC system_header | ||
namespace std { | ||
template<typename T> T &&declval(); | ||
|
||
template<typename...Ts> struct common_type {}; | ||
template<typename A, typename B> struct common_type<A, B> { | ||
// Under the rules in the standard, this always produces a | ||
// reference type. | ||
typedef decltype(true ? declval<A>() : declval<B>()) type; | ||
}; | ||
} | ||
|
||
#else | ||
|
||
#define BE_THE_HEADER | ||
#include "libstdcxx_common_type_hack.cpp" | ||
|
||
using T = int; | ||
using T = std::common_type<int, int>::type; | ||
|
||
using U = int; // expected-note {{here}} | ||
using U = decltype(true ? std::declval<int>() : std::declval<int>()); // expected-error {{different types}} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters