PR13978: A 'decltype' DeclSpec has an expression representation, not a type
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 1 Oct 2012 20:35:07 +0000 (20:35 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 1 Oct 2012 20:35:07 +0000 (20:35 +0000)
representation. Fix crash if it appears in the return type of a member function
definition.

llvm-svn: 164967

clang/lib/Sema/SemaDecl.cpp
clang/test/SemaCXX/decltype-overloaded-functions.cpp

index 593c110..4382432 100644 (file)
@@ -3400,7 +3400,6 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
   switch (DS.getTypeSpecType()) {
   case DeclSpec::TST_typename:
   case DeclSpec::TST_typeofType:
-  case DeclSpec::TST_decltype:
   case DeclSpec::TST_underlyingType:
   case DeclSpec::TST_atomic: {
     // Grab the type from the parser.
@@ -3424,6 +3423,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
     break;
   }
 
+  case DeclSpec::TST_decltype:
   case DeclSpec::TST_typeofExpr: {
     Expr *E = DS.getRepAsExpr();
     ExprResult Result = S.RebuildExprInCurrentInstantiation(E);
index b0a43a9..2ed4465 100644 (file)
@@ -13,3 +13,18 @@ struct K {
   void f(int); // expected-note{{possible target for call}}
 };
 S<K> b; // expected-note{{in instantiation of template class 'S<K>' requested here}}
+
+namespace PR13978 {
+  template<typename T> struct S { decltype(1) f(); };
+  template<typename T> decltype(1) S<T>::f() { return 1; }
+
+  // This case is ill-formed (no diagnostic required) because the decltype
+  // expressions are functionally equivalent but not equivalent. It would
+  // be acceptable for us to reject this case.
+  template<typename T> struct U { struct A {}; decltype(A{}) f(); };
+  template<typename T> decltype(typename U<T>::A{}) U<T>::f() {}
+
+  // This case is valid.
+  template<typename T> struct V { struct A {}; decltype(typename V<T>::A{}) f(); };
+  template<typename T> decltype(typename V<T>::A{}) V<T>::f() {}
+}