Clear LookupResult object if invalid candidate is found.
If source code is invalid, error recovery can lead to name lookup in a set containing invalid declaration. The lookup is stopped once found such declaration, but LookupResult object could remain in inconsistent state. Its destructor triggered a check, which caused assert violation.
This patch fixes PR16964 and PR12791.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189916 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 0d0603f..165a1af 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -7742,8 +7742,10 @@
       // This can happen because of dependent hiding.
       if (isa<UsingShadowDecl>(*I))
         continue;
-      else
+      else {
+        R.clear();
         return ExprError();
+      }
     }
 
     // Expand using declarations.
@@ -7778,8 +7780,10 @@
       = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
                                                             Old->getNameLoc(),
                                                         Old->getNamingClass()));
-    if (!NamingClass)
+    if (!NamingClass) {
+      R.clear();
       return ExprError();
+    }
 
     R.setNamingClass(NamingClass);
   }
@@ -7797,8 +7801,10 @@
   if (Old->hasExplicitTemplateArgs() &&
       getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
                                               Old->getNumTemplateArgs(),
-                                              TransArgs))
+                                              TransArgs)) {
+    R.clear();
     return ExprError();
+  }
 
   return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
                                             Old->requiresADL(), &TransArgs);
diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp
index f5682bd..0b15bb0 100644
--- a/test/SemaCXX/crashes.cpp
+++ b/test/SemaCXX/crashes.cpp
@@ -171,3 +171,50 @@
     int& x = dimenX.*sides;
   }
 }
+
+namespace pr16964 {
+  template<typename> struct bs {
+    bs();
+    static int* member();
+    member();  // expected-error{{C++ requires a type specifier for all declarations}}
+    static member();  // expected-error{{C++ requires a type specifier for all declarations}}
+    static int* member(int);
+  };
+
+  template<typename T> bs<T>::bs() { member; }
+
+  bs<int> test() {
+    return bs<int>();
+  }
+}
+
+namespace pr12791 {
+  template<class _Alloc> class allocator {};
+  template<class _CharT> struct char_traits;
+  struct input_iterator_tag {};
+  struct forward_iterator_tag : public input_iterator_tag {};
+
+  template<typename _CharT, typename _Traits, typename _Alloc> struct basic_string {
+    struct _Alloc_hider : _Alloc {};
+    mutable _Alloc_hider _M_dataplus;
+    template<class _InputIterator> basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc());
+    template<class _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag);
+    template<class _FwdIterator> static _CharT* _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, forward_iterator_tag);
+    static _CharT* _S_construct(size_type __req, _CharT __c, const _Alloc& __a); // expected-error{{unknown type name 'size_type'}}
+  };
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+  template<typename _InputIterator>
+  basic_string<_CharT, _Traits, _Alloc>:: basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
+  : _M_dataplus(_S_construct(__beg, __end, __a), __a) {}
+
+  template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > struct basic_stringbuf {
+    typedef _CharT char_type;
+    typedef basic_string<char_type, _Traits, _Alloc> __string_type;
+    typedef typename __string_type::size_type __size_type;
+    __string_type str() const {__string_type((char_type*)0,(char_type*)0);}
+  };
+
+  template class basic_stringbuf<char>;
+}
+