r189916 - Clear LookupResult object if invalid candidate is found.

Serge Pavlov sepavloff at gmail.com
Tue Sep 3 21:50:29 PDT 2013


Author: sepavloff
Date: Tue Sep  3 23:50:29 2013
New Revision: 189916

URL: http://llvm.org/viewvc/llvm-project?rev=189916&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaCXX/crashes.cpp

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=189916&r1=189915&r2=189916&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Sep  3 23:50:29 2013
@@ -7742,8 +7742,10 @@ TreeTransform<Derived>::TransformUnresol
       // 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 @@ TreeTransform<Derived>::TransformUnresol
       = 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 @@ TreeTransform<Derived>::TransformUnresol
   if (Old->hasExplicitTemplateArgs() &&
       getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
                                               Old->getNumTemplateArgs(),
-                                              TransArgs))
+                                              TransArgs)) {
+    R.clear();
     return ExprError();
+  }
 
   return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
                                             Old->requiresADL(), &TransArgs);

Modified: cfe/trunk/test/SemaCXX/crashes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=189916&r1=189915&r2=189916&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/crashes.cpp (original)
+++ cfe/trunk/test/SemaCXX/crashes.cpp Tue Sep  3 23:50:29 2013
@@ -171,3 +171,50 @@ namespace test3 {
     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>;
+}
+





More information about the cfe-commits mailing list