forked from OSchip/llvm-project
Implement CWG1170, which makes access-control errors into template
argument deduction failures. Only implemented in C++0x, since this is a significant change in behavior from C++98/03. llvm-svn: 131209
This commit is contained in:
parent
7c6c90b35d
commit
347d626cf7
|
@ -32,6 +32,7 @@ td {
|
|||
</ul>
|
||||
<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a></li>
|
||||
<ul>
|
||||
<li><a href="#cxx_access_control_sfinae">C++0x SFINAE includes access control</a></li>
|
||||
<li><a href="#cxx_alias_templates">C++0x alias templates</a></li>
|
||||
<li><a href="#cxx_attributes">C++0x attributes</a></li>
|
||||
<li><a href="#cxx_decltype">C++0x <tt>decltype()</tt></a></li>
|
||||
|
@ -379,6 +380,10 @@ not yet implemented will be noted.</p>
|
|||
<p>Use <tt>__has_feature(cxx_decltype)</tt> to determine if support for the
|
||||
<tt>decltype()</tt> specifier is enabled.</p>
|
||||
|
||||
<h3 id="cxx_access_control_sfinae">C++0x SFINAE includes access control</h3>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_access_control_sfinae)</tt> to determine whether access-control errors (e.g., calling a private constructor) are considered to be template argument deduction errors (aka SFINAE errors), per <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170">C++ DR1170</a>.</p>
|
||||
|
||||
<h3 id="cxx_alias_templates">C++0x alias templates</h3>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_alias_templates)</tt> to determine if support for
|
||||
|
|
|
@ -557,6 +557,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
|||
.Case("ownership_returns", true)
|
||||
.Case("ownership_takes", true)
|
||||
// C++0x features
|
||||
.Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x)
|
||||
.Case("cxx_alias_templates", LangOpts.CPlusPlus0x)
|
||||
.Case("cxx_attributes", LangOpts.CPlusPlus0x)
|
||||
.Case("cxx_auto_type", LangOpts.CPlusPlus0x)
|
||||
|
|
|
@ -577,9 +577,12 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
|
|||
break;
|
||||
|
||||
case DiagnosticIDs::SFINAE_AccessControl:
|
||||
// Unless access checking is specifically called out as a SFINAE
|
||||
// error, report this diagnostic.
|
||||
if (!SemaRef.AccessCheckingSFINAE)
|
||||
// Per C++ Core Issue 1170, access control is part of SFINAE.
|
||||
// Additionally, the AccessCheckingSFINAE flag can be used to temporary
|
||||
// make access control a part of SFINAE for the purposes of checking
|
||||
// type traits.
|
||||
if (!SemaRef.AccessCheckingSFINAE &&
|
||||
!SemaRef.getLangOptions().CPlusPlus0x)
|
||||
break;
|
||||
|
||||
case DiagnosticIDs::SFINAE_SubstitutionFailure:
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
|
||||
|
||||
#if !__has_feature(cxx_access_control_sfinae)
|
||||
# error No support for access control as part of SFINAE?
|
||||
#endif
|
||||
|
||||
typedef char yes_type;
|
||||
typedef char (&no_type)[2];
|
||||
|
||||
template<unsigned N> struct unsigned_c { };
|
||||
|
||||
template<typename T>
|
||||
class has_copy_constructor {
|
||||
static T t;
|
||||
|
||||
template<typename U> static yes_type check(unsigned_c<sizeof(U(t))> * = 0);
|
||||
template<typename U> static no_type check(...);
|
||||
|
||||
public:
|
||||
static const bool value = (sizeof(check<T>(0)) == sizeof(yes_type));
|
||||
};
|
||||
|
||||
struct HasCopy { };
|
||||
|
||||
struct HasNonConstCopy {
|
||||
HasNonConstCopy(HasNonConstCopy&);
|
||||
};
|
||||
|
||||
struct HasDeletedCopy {
|
||||
HasDeletedCopy(const HasDeletedCopy&) = delete;
|
||||
};
|
||||
|
||||
struct HasPrivateCopy {
|
||||
private:
|
||||
HasPrivateCopy(const HasPrivateCopy&);
|
||||
};
|
||||
|
||||
int check0[has_copy_constructor<HasCopy>::value? 1 : -1];
|
||||
int check1[has_copy_constructor<HasNonConstCopy>::value? 1 : -1];
|
||||
int check2[has_copy_constructor<HasDeletedCopy>::value? -1 : 1];
|
||||
int check3[has_copy_constructor<HasPrivateCopy>::value? -1 : 1];
|
Loading…
Reference in New Issue