[cfe-commits] r155621 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiate.cpp test/SemaCXX/alias-template.cpp

Richard Smith richard-llvm at metafoo.co.uk
Thu Apr 26 00:24:09 PDT 2012


Author: rsmith
Date: Thu Apr 26 02:24:08 2012
New Revision: 155621

URL: http://llvm.org/viewvc/llvm-project?rev=155621&view=rev
Log:
PR12647: An alias template instantiation which occurs in a SFINAE context is
itself a SFINAE context.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaCXX/alias-template.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=155621&r1=155620&r2=155621&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Apr 26 02:24:08 2012
@@ -638,8 +638,13 @@
        ++Active) 
   {
     switch(Active->Kind) {
-    case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
     case ActiveTemplateInstantiation::TemplateInstantiation:
+      // An instantiation of an alias template may or may not be a SFINAE
+      // context, depending on what else is on the stack.
+      if (isa<TypeAliasTemplateDecl>(reinterpret_cast<Decl *>(Active->Entity)))
+        break;
+      // Fall through.
+    case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
     case ActiveTemplateInstantiation::ExceptionSpecInstantiation:
       // This is a template instantiation, so there is no SFINAE.
       return llvm::Optional<TemplateDeductionInfo *>();

Modified: cfe/trunk/test/SemaCXX/alias-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/alias-template.cpp?rev=155621&r1=155620&r2=155621&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/alias-template.cpp (original)
+++ cfe/trunk/test/SemaCXX/alias-template.cpp Thu Apr 26 02:24:08 2012
@@ -145,3 +145,30 @@
   template<typename T, typename U> struct S;
   template<typename T> template<typename U> using SS = S<T, U>; // expected-error {{extraneous template parameter list in alias template declaration}}
 }
+
+// PR12647
+namespace SFINAE {
+  template<bool> struct enable_if; // expected-note 2{{here}}
+  template<> struct enable_if<true> { using type = void; };
+
+  template<typename T> struct is_enum { static constexpr bool value = __is_enum(T); };
+
+  template<typename T> using EnableIf = typename enable_if<T::value>::type; // expected-error {{undefined template}}
+  template<typename T> using DisableIf = typename enable_if<!T::value>::type; // expected-error {{undefined template}}
+
+  template<typename T> EnableIf<is_enum<T>> f();
+  template<typename T> DisableIf<is_enum<T>> f();
+
+  enum E { e };
+
+  int main() {
+    f<int>();
+    f<E>();
+  }
+
+  template<typename T, typename U = EnableIf<is_enum<T>>> struct fail1 {}; // expected-note {{here}}
+  template<typename T> struct fail2 : DisableIf<is_enum<T>> {}; // expected-note {{here}}
+
+  fail1<int> f1; // expected-note {{here}}
+  fail2<E> f2; // expected-note {{here}}
+}





More information about the cfe-commits mailing list