[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