[cfe-commits] r102684 - in /cfe/trunk: lib/CodeGen/CGException.cpp lib/CodeGen/CGRTTI.cpp lib/CodeGen/CodeGenModule.h test/CodeGenCXX/exceptions-no-rtti.cpp

John McCall rjmccall at apple.com
Thu Apr 29 18:15:21 PDT 2010


Author: rjmccall
Date: Thu Apr 29 20:15:21 2010
New Revision: 102684

URL: http://llvm.org/viewvc/llvm-project?rev=102684&view=rev
Log:
Fix -fno-rtti -fexceptions by forcing the emission of (non-"builtin") RTTI
when used by the exceptions routines.  Fixes PR 6974.


Added:
    cfe/trunk/test/CodeGenCXX/exceptions-no-rtti.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/CGRTTI.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=102684&r1=102683&r2=102684&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Thu Apr 29 20:15:21 2010
@@ -271,7 +271,7 @@
 
   // Now throw the exception.
   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
-  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType);
+  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, true);
 
   // The address of the destructor.  If the exception type has a
   // trivial destructor (or isn't a record), we just pass null.
@@ -371,7 +371,7 @@
     QualType Ty = Proto->getExceptionType(i);
     QualType ExceptType
       = Ty.getNonReferenceType().getUnqualifiedType();
-    llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType);
+    llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType, true);
     SelectorArgs.push_back(EHType);
   }
   if (Proto->getNumExceptions())
@@ -494,7 +494,7 @@
       // are ignored.
       QualType CaughtType = C->getCaughtType().getNonReferenceType();
       llvm::Value *EHTypeInfo
-        = CGM.GetAddrOfRTTIDescriptor(CaughtType.getUnqualifiedType());
+        = CGM.GetAddrOfRTTIDescriptor(CaughtType.getUnqualifiedType(), true);
       SelectorArgs.push_back(EHTypeInfo);
     } else {
       // null indicates catch all

Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=102684&r1=102683&r2=102684&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Thu Apr 29 20:15:21 2010
@@ -148,6 +148,9 @@
   };
   
   /// BuildTypeInfo - Build the RTTI type info struct for the given type.
+  ///
+  /// \param Force - true to force the creation of this RTTI value
+  /// \param ForEH - true if this is for exception handling
   llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
 };
 }
@@ -242,9 +245,10 @@
 }
 
 /// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
-/// the given type exists somewhere else, and that we should not emit the typ
+/// the given type exists somewhere else, and that we should not emit the type
 /// information in this translation unit.
-bool ShouldUseExternalRTTIDescriptor(QualType Ty) {
+static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
+                                            QualType Ty) {
   // Type info for builtin types is defined in the standard library.
   if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
     return TypeInfoIsInStandardLibrary(BuiltinTy);
@@ -254,6 +258,9 @@
   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
     return TypeInfoIsInStandardLibrary(PointerTy);
 
+  // If RTTI is disabled, don't consider key functions.
+  if (!Context.getLangOptions().RTTI) return false;
+
   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
     if (!RD->hasDefinition())
@@ -449,7 +456,8 @@
   Fields.push_back(VTable);
 }
 
-llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty,
+                                           bool Force) {
   // We want to operate on the canonical type.
   Ty = CGM.getContext().getCanonicalType(Ty);
 
@@ -463,7 +471,7 @@
     return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
   
   // Check if there is already an external RTTI descriptor for this type.
-  if (!Force && ShouldUseExternalRTTIDescriptor(Ty))
+  if (!Force && ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty))
     return GetAddrOfExternalRTTIDescriptor(Ty);
 
   llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
@@ -782,12 +790,16 @@
   Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
 }
 
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) {
-  if (!getContext().getLangOptions().RTTI) {
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
+                                                       bool ForEH) {
+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+  // FIXME: should we even be calling this method if RTTI is disabled
+  // and it's not for EH?
+  if (!ForEH && !getContext().getLangOptions().RTTI) {
     const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     return llvm::Constant::getNullValue(Int8PtrTy);
   }
-  
+
   return RTTIBuilder(*this).BuildTypeInfo(Ty);
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=102684&r1=102683&r2=102684&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Apr 29 20:15:21 2010
@@ -232,7 +232,7 @@
 
   /// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor 
   /// for the given type.
-  llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty);
+  llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
 
   /// GetAddrOfThunk - Get the address of the thunk for the given global decl.
   llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk);

Added: cfe/trunk/test/CodeGenCXX/exceptions-no-rtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions-no-rtti.cpp?rev=102684&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions-no-rtti.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/exceptions-no-rtti.cpp Thu Apr 29 20:15:21 2010
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fno-rtti -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTIN5test11AE = weak_odr constant
+// CHECK: @_ZTIN5test11BE = weak_odr constant
+// CHECK: @_ZTIN5test11CE = weak_odr constant
+// CHECK: @_ZTIN5test11DE = weak_odr constant
+// CHECK: @_ZTIPN5test11DE = weak_odr constant {{.*}} @_ZTIN5test11DE
+
+// PR6974: this shouldn't crash
+namespace test0 {
+  class err {};
+
+  void f(void) {
+    try {
+    } catch (err &) {
+    }
+  }
+}
+
+namespace test1 {
+  // These classes have key functions defined out-of-line.
+  // Under normal circumstances, we wouldn't generate RTTI for them;
+  // under -fno-rtti, we generate RTTI only when required by EH.
+  class A { virtual void foo(); };
+  class B { virtual void foo(); };
+  class C { virtual void foo(); };
+  class D { virtual void foo(); };
+
+  void opaque();
+
+  void test0() {
+    throw A();
+  }
+
+  void test1() throw(B) {
+    opaque();
+  }
+
+  void test2() {
+    try {
+      opaque();
+    } catch (C&) {}
+  }
+
+  void test3(D *ptr) {
+    throw ptr;
+  };
+}





More information about the cfe-commits mailing list