From: Douglas Gregor
+
Use __has_feature(cxx_decltype) to determine if support for the decltype() specifier is enabled.
+Use __has_feature(cxx_access_control_sfinae) to determine whether access-control errors (e.g., calling a private constructor) are considered to be template argument deduction errors (aka SFINAE errors), per C++ DR1170.
+Use __has_feature(cxx_alias_templates) to determine if support for
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 3b4f042291..2d04d770f5 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -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)
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index a994133afe..6ca8be2999 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -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:
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp
new file mode 100644
index 0000000000..d3af0d4b91
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp
@@ -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