[cfe-commits] r153120 - in /cfe/trunk: lib/CodeGen/CGVTables.cpp test/CodeGenCXX/thunk-use-after-free.cpp

Benjamin Kramer benny.kra at googlemail.com
Tue Mar 20 13:18:14 PDT 2012


Author: d0k
Date: Tue Mar 20 15:18:13 2012
New Revision: 153120

URL: http://llvm.org/viewvc/llvm-project?rev=153120&view=rev
Log:
Fix a use-after-free in thunk emission. EmitThunk may call RAUW on Init, invalidating the pointer.

Fixes PR12284. The test case only triggered under asan/valgrind, but it's better than nothing.

Added:
    cfe/trunk/test/CodeGenCXX/thunk-use-after-free.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGVTables.cpp

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=153120&r1=153119&r2=153120&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Tue Mar 20 15:18:13 2012
@@ -584,8 +584,8 @@
             VTableThunks[NextVTableThunkIndex].first == I) {
           const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
         
-          Init = CGM.GetAddrOfThunk(GD, Thunk);
           MaybeEmitThunkAvailableExternally(GD, Thunk);
+          Init = CGM.GetAddrOfThunk(GD, Thunk);
 
           NextVTableThunkIndex++;
         } else {

Added: cfe/trunk/test/CodeGenCXX/thunk-use-after-free.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunk-use-after-free.cpp?rev=153120&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/thunk-use-after-free.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/thunk-use-after-free.cpp Tue Mar 20 15:18:13 2012
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm-only -O1 %s
+// This used to crash under asan and valgrind.
+// PR12284
+
+template < typename _Tp > struct new_allocator
+{
+  typedef _Tp *pointer;
+  template < typename > struct rebind {
+    typedef new_allocator other;
+  };
+};
+template < typename _Tp > struct allocator:new_allocator < _Tp > {
+};
+template < typename _Tp, typename _Alloc > struct _Vector_base {
+  typedef typename _Alloc::template rebind < _Tp >::other _Tp_alloc_type;
+  struct _Vector_impl {
+    typename _Tp_alloc_type::pointer _M_end_of_storage;
+  };
+  _Vector_base () {
+    foo((int *) this->_M_impl._M_end_of_storage);
+  }
+  void foo(int *);
+  _Vector_impl _M_impl;
+};
+template < typename _Tp, typename _Alloc =
+allocator < _Tp > >struct vector:_Vector_base < _Tp, _Alloc > { };
+
+
+template < class T> struct HHH {};
+struct DDD { int x_;};
+struct Data;
+struct X1;
+struct CCC:DDD {   virtual void xxx (HHH < X1 >); };
+template < class SSS > struct EEE:vector < HHH < SSS > > { };
+template < class SSS, class = EEE < SSS > >class FFF { };
+template < class SSS, class GGG = EEE < SSS > >class AAA:FFF <GGG> { };
+class BBB:virtual CCC {
+  void xxx (HHH < X1 >);
+  vector < HHH < X1 > >aaa;
+};
+class ZZZ:AAA < Data >, BBB { virtual ZZZ *ppp () ; };
+ZZZ * ZZZ::ppp () { return new ZZZ; }





More information about the cfe-commits mailing list