зеркало из https://github.com/microsoft/clang-1.git
Emit standard-library RTTI with external linkage, not weak_odr.
Apply hidden visibility to most RTTI; libstdc++ does not rely on exact pointer equality for the type info (just the type info names). Apply the same optimization to RTTI that we do to vtables. Fixes PR5962. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110192 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
72905cfa81
Коммит
cbfe50224b
|
@ -244,11 +244,9 @@ static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
|
|||
return TypeInfoIsInStandardLibrary(BuiltinTy);
|
||||
}
|
||||
|
||||
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
|
||||
/// the given type exists somewhere else, and that we should not emit the type
|
||||
/// information in this translation unit.
|
||||
static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
|
||||
QualType Ty) {
|
||||
/// IsStandardLibraryRTTIDescriptor - Returns whether the type
|
||||
/// information for the given type exists in the standard library.
|
||||
static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
|
||||
// Type info for builtin types is defined in the standard library.
|
||||
if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
|
||||
return TypeInfoIsInStandardLibrary(BuiltinTy);
|
||||
|
@ -258,6 +256,15 @@ static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
|
|||
if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
|
||||
return TypeInfoIsInStandardLibrary(PointerTy);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
|
||||
/// the given type exists somewhere else, and that we should not emit the type
|
||||
/// information in this translation unit. Assumes that it is not a
|
||||
/// standard-library type.
|
||||
static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
|
||||
QualType Ty) {
|
||||
// If RTTI is disabled, don't consider key functions.
|
||||
if (!Context.getLangOptions().RTTI) return false;
|
||||
|
||||
|
@ -456,8 +463,7 @@ void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
|
|||
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);
|
||||
|
||||
|
@ -469,19 +475,26 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty,
|
|||
llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
|
||||
if (OldGV && !OldGV->isDeclaration())
|
||||
return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
|
||||
|
||||
|
||||
// Check if there is already an external RTTI descriptor for this type.
|
||||
if (!Force && ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty))
|
||||
bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
|
||||
if (!Force &&
|
||||
(IsStdLib || ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty)))
|
||||
return GetAddrOfExternalRTTIDescriptor(Ty);
|
||||
|
||||
llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
|
||||
// Emit the standard library with external linkage.
|
||||
llvm::GlobalVariable::LinkageTypes Linkage;
|
||||
if (IsStdLib)
|
||||
Linkage = llvm::GlobalValue::ExternalLinkage;
|
||||
else
|
||||
Linkage = getTypeInfoLinkage(Ty);
|
||||
|
||||
// Add the vtable pointer.
|
||||
BuildVTablePointer(cast<Type>(Ty));
|
||||
|
||||
// And the name.
|
||||
Fields.push_back(BuildName(Ty, DecideHidden(Ty), Linkage));
|
||||
|
||||
|
||||
switch (Ty->getTypeClass()) {
|
||||
default: assert(false && "Unhandled type class!");
|
||||
|
||||
|
@ -551,7 +564,15 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty,
|
|||
OldGV->replaceAllUsesWith(NewPtr);
|
||||
OldGV->eraseFromParent();
|
||||
}
|
||||
|
||||
|
||||
// GCC only relies on the uniqueness of the type names, not the
|
||||
// type_infos themselves, so we can emit these as hidden symbols.
|
||||
if (const RecordType *RT = dyn_cast<RecordType>(Ty))
|
||||
CGM.setTypeVisibility(GV, cast<CXXRecordDecl>(RT->getDecl()),
|
||||
/*ForRTTI*/ true);
|
||||
else if (Linkage == llvm::GlobalValue::WeakODRLinkage)
|
||||
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
|
||||
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||
}
|
||||
|
||||
|
|
|
@ -2925,39 +2925,7 @@ CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,
|
|||
VTable->setLinkage(Linkage);
|
||||
|
||||
// Set the right visibility.
|
||||
CGM.setGlobalVisibility(VTable, RD);
|
||||
|
||||
// It's okay to have multiple copies of a vtable, so don't make the
|
||||
// dynamic linker unique them. Suppress this optimization if it's
|
||||
// possible that there might be unresolved references elsewhere
|
||||
// which can only be resolved by this emission.
|
||||
if (Linkage == llvm::GlobalVariable::WeakODRLinkage &&
|
||||
VTable->getVisibility() == llvm::GlobalVariable::DefaultVisibility &&
|
||||
!RD->hasAttr<VisibilityAttr>()) {
|
||||
switch (RD->getTemplateSpecializationKind()) {
|
||||
|
||||
// Every use of a non-template or explicitly-specialized class's
|
||||
// vtable has to emit it.
|
||||
case TSK_ExplicitSpecialization:
|
||||
case TSK_Undeclared:
|
||||
// Implicit instantiations can ignore the possibility of an
|
||||
// explicit instantiation declaration because there necessarily
|
||||
// must be an EI definition somewhere with default visibility.
|
||||
case TSK_ImplicitInstantiation:
|
||||
// If there's a key function, there may be translation units
|
||||
// that don't have the key function's definition.
|
||||
if (!CGM.Context.getKeyFunction(RD))
|
||||
// Otherwise, drop the visibility to hidden.
|
||||
VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
break;
|
||||
|
||||
// We have to disable the optimization if this is an EI definition
|
||||
// because there might be EI declarations in other shared objects.
|
||||
case TSK_ExplicitInstantiationDefinition:
|
||||
case TSK_ExplicitInstantiationDeclaration:
|
||||
break;
|
||||
}
|
||||
}
|
||||
CGM.setTypeVisibility(VTable, RD, /*ForRTTI*/ false);
|
||||
}
|
||||
|
||||
llvm::GlobalVariable *
|
||||
|
|
|
@ -216,6 +216,57 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the symbol visibility of type information (vtable and RTTI)
|
||||
/// associated with the given type.
|
||||
void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
|
||||
const CXXRecordDecl *RD,
|
||||
bool IsForRTTI) const {
|
||||
setGlobalVisibility(GV, RD);
|
||||
|
||||
// We want to drop the visibility to hidden for weak type symbols.
|
||||
// This isn't possible if there might be unresolved references
|
||||
// elsewhere that rely on this symbol being visible.
|
||||
|
||||
// Preconditions.
|
||||
if (GV->getLinkage() != llvm::GlobalVariable::WeakODRLinkage ||
|
||||
GV->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
|
||||
return;
|
||||
|
||||
// Don't override an explicit visibility attribute.
|
||||
if (RD->hasAttr<VisibilityAttr>())
|
||||
return;
|
||||
|
||||
switch (RD->getTemplateSpecializationKind()) {
|
||||
// We have to disable the optimization if this is an EI definition
|
||||
// because there might be EI declarations in other shared objects.
|
||||
case TSK_ExplicitInstantiationDefinition:
|
||||
case TSK_ExplicitInstantiationDeclaration:
|
||||
return;
|
||||
|
||||
// Every use of a non-template or explicitly-specialized class's
|
||||
// type information has to emit it.
|
||||
case TSK_ExplicitSpecialization:
|
||||
case TSK_Undeclared:
|
||||
break;
|
||||
|
||||
// Implicit instantiations can ignore the possibility of an
|
||||
// explicit instantiation declaration because there necessarily
|
||||
// must be an EI definition somewhere with default visibility.
|
||||
case TSK_ImplicitInstantiation:
|
||||
break;
|
||||
}
|
||||
|
||||
// If there's a key function, there may be translation units
|
||||
// that don't have the key function's definition. But ignore
|
||||
// this if we're emitting RTTI under -fno-rtti.
|
||||
if (!IsForRTTI || Features.RTTI)
|
||||
if (Context.getKeyFunction(RD))
|
||||
return;
|
||||
|
||||
// Otherwise, drop the visibility to hidden.
|
||||
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
}
|
||||
|
||||
llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
|
||||
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
|
||||
|
||||
|
|
|
@ -270,6 +270,11 @@ public:
|
|||
/// GlobalValue.
|
||||
void setGlobalVisibility(llvm::GlobalValue *GV, const Decl *D) const;
|
||||
|
||||
/// setTypeVisibility - Set the visibility for the given global
|
||||
/// value which holds information about a type.
|
||||
void setTypeVisibility(llvm::GlobalValue *GV, const CXXRecordDecl *D,
|
||||
bool IsForRTTI) const;
|
||||
|
||||
llvm::Constant *GetAddrOfGlobal(GlobalDecl GD) {
|
||||
if (isa<CXXConstructorDecl>(GD.getDecl()))
|
||||
return GetAddrOfCXXConstructor(cast<CXXConstructorDecl>(GD.getDecl()),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// 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
|
||||
// CHECK: @_ZTIN5test11AE = weak_odr hidden constant
|
||||
// CHECK: @_ZTIN5test11BE = weak_odr hidden constant
|
||||
// CHECK: @_ZTIN5test11CE = weak_odr hidden constant
|
||||
// CHECK: @_ZTIN5test11DE = weak_odr hidden constant
|
||||
// CHECK: @_ZTIPN5test11DE = weak_odr hidden constant {{.*}} @_ZTIN5test11DE
|
||||
|
||||
// PR6974: this shouldn't crash
|
||||
namespace test0 {
|
||||
|
@ -18,9 +18,12 @@ namespace test0 {
|
|||
}
|
||||
|
||||
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.
|
||||
// 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. But
|
||||
// everything gets hidden visibility because we assume that all
|
||||
// users are also compiled under -fno-rtti and therefore will be
|
||||
// emitting RTTI regardless of key function.
|
||||
class A { virtual void foo(); };
|
||||
class B { virtual void foo(); };
|
||||
class C { virtual void foo(); };
|
||||
|
|
|
@ -14,60 +14,60 @@ namespace __cxxabiv1 {
|
|||
__fundamental_type_info::~__fundamental_type_info() { }
|
||||
}
|
||||
|
||||
// CHECK: @_ZTIv = weak_odr constant
|
||||
// CHECK: @_ZTIPv = weak_odr constant
|
||||
// CHECK: @_ZTIPKv = weak_odr constant
|
||||
// CHECK: @_ZTIDi = weak_odr constant
|
||||
// CHECK: @_ZTIPDi = weak_odr constant
|
||||
// CHECK: @_ZTIPKDi = weak_odr constant
|
||||
// CHECK: @_ZTIDs = weak_odr constant
|
||||
// CHECK: @_ZTIPDs = weak_odr constant
|
||||
// CHECK: @_ZTIPKDs = weak_odr constant
|
||||
// CHECK: @_ZTIy = weak_odr constant
|
||||
// CHECK: @_ZTIPy = weak_odr constant
|
||||
// CHECK: @_ZTIPKy = weak_odr constant
|
||||
// CHECK: @_ZTIx = weak_odr constant
|
||||
// CHECK: @_ZTIPx = weak_odr constant
|
||||
// CHECK: @_ZTIPKx = weak_odr constant
|
||||
// CHECK: @_ZTIw = weak_odr constant
|
||||
// CHECK: @_ZTIPw = weak_odr constant
|
||||
// CHECK: @_ZTIPKw = weak_odr constant
|
||||
// CHECK: @_ZTIt = weak_odr constant
|
||||
// CHECK: @_ZTIPt = weak_odr constant
|
||||
// CHECK: @_ZTIPKt = weak_odr constant
|
||||
// CHECK: @_ZTIs = weak_odr constant
|
||||
// CHECK: @_ZTIPs = weak_odr constant
|
||||
// CHECK: @_ZTIPKs = weak_odr constant
|
||||
// CHECK: @_ZTIm = weak_odr constant
|
||||
// CHECK: @_ZTIPm = weak_odr constant
|
||||
// CHECK: @_ZTIPKm = weak_odr constant
|
||||
// CHECK: @_ZTIl = weak_odr constant
|
||||
// CHECK: @_ZTIPl = weak_odr constant
|
||||
// CHECK: @_ZTIPKl = weak_odr constant
|
||||
// CHECK: @_ZTIj = weak_odr constant
|
||||
// CHECK: @_ZTIPj = weak_odr constant
|
||||
// CHECK: @_ZTIPKj = weak_odr constant
|
||||
// CHECK: @_ZTIi = weak_odr constant
|
||||
// CHECK: @_ZTIPi = weak_odr constant
|
||||
// CHECK: @_ZTIPKi = weak_odr constant
|
||||
// CHECK: @_ZTIh = weak_odr constant
|
||||
// CHECK: @_ZTIPh = weak_odr constant
|
||||
// CHECK: @_ZTIPKh = weak_odr constant
|
||||
// CHECK: @_ZTIf = weak_odr constant
|
||||
// CHECK: @_ZTIPf = weak_odr constant
|
||||
// CHECK: @_ZTIPKf = weak_odr constant
|
||||
// CHECK: @_ZTIe = weak_odr constant
|
||||
// CHECK: @_ZTIPe = weak_odr constant
|
||||
// CHECK: @_ZTIPKe = weak_odr constant
|
||||
// CHECK: @_ZTId = weak_odr constant
|
||||
// CHECK: @_ZTIPd = weak_odr constant
|
||||
// CHECK: @_ZTIPKd = weak_odr constant
|
||||
// CHECK: @_ZTIc = weak_odr constant
|
||||
// CHECK: @_ZTIPc = weak_odr constant
|
||||
// CHECK: @_ZTIPKc = weak_odr constant
|
||||
// CHECK: @_ZTIb = weak_odr constant
|
||||
// CHECK: @_ZTIPb = weak_odr constant
|
||||
// CHECK: @_ZTIPKb = weak_odr constant
|
||||
// CHECK: @_ZTIa = weak_odr constant
|
||||
// CHECK: @_ZTIPa = weak_odr constant
|
||||
// CHECK: @_ZTIPKa = weak_odr constant
|
||||
// CHECK: @_ZTIv = constant
|
||||
// CHECK: @_ZTIPv = constant
|
||||
// CHECK: @_ZTIPKv = constant
|
||||
// CHECK: @_ZTIDi = constant
|
||||
// CHECK: @_ZTIPDi = constant
|
||||
// CHECK: @_ZTIPKDi = constant
|
||||
// CHECK: @_ZTIDs = constant
|
||||
// CHECK: @_ZTIPDs = constant
|
||||
// CHECK: @_ZTIPKDs = constant
|
||||
// CHECK: @_ZTIy = constant
|
||||
// CHECK: @_ZTIPy = constant
|
||||
// CHECK: @_ZTIPKy = constant
|
||||
// CHECK: @_ZTIx = constant
|
||||
// CHECK: @_ZTIPx = constant
|
||||
// CHECK: @_ZTIPKx = constant
|
||||
// CHECK: @_ZTIw = constant
|
||||
// CHECK: @_ZTIPw = constant
|
||||
// CHECK: @_ZTIPKw = constant
|
||||
// CHECK: @_ZTIt = constant
|
||||
// CHECK: @_ZTIPt = constant
|
||||
// CHECK: @_ZTIPKt = constant
|
||||
// CHECK: @_ZTIs = constant
|
||||
// CHECK: @_ZTIPs = constant
|
||||
// CHECK: @_ZTIPKs = constant
|
||||
// CHECK: @_ZTIm = constant
|
||||
// CHECK: @_ZTIPm = constant
|
||||
// CHECK: @_ZTIPKm = constant
|
||||
// CHECK: @_ZTIl = constant
|
||||
// CHECK: @_ZTIPl = constant
|
||||
// CHECK: @_ZTIPKl = constant
|
||||
// CHECK: @_ZTIj = constant
|
||||
// CHECK: @_ZTIPj = constant
|
||||
// CHECK: @_ZTIPKj = constant
|
||||
// CHECK: @_ZTIi = constant
|
||||
// CHECK: @_ZTIPi = constant
|
||||
// CHECK: @_ZTIPKi = constant
|
||||
// CHECK: @_ZTIh = constant
|
||||
// CHECK: @_ZTIPh = constant
|
||||
// CHECK: @_ZTIPKh = constant
|
||||
// CHECK: @_ZTIf = constant
|
||||
// CHECK: @_ZTIPf = constant
|
||||
// CHECK: @_ZTIPKf = constant
|
||||
// CHECK: @_ZTIe = constant
|
||||
// CHECK: @_ZTIPe = constant
|
||||
// CHECK: @_ZTIPKe = constant
|
||||
// CHECK: @_ZTId = constant
|
||||
// CHECK: @_ZTIPd = constant
|
||||
// CHECK: @_ZTIPKd = constant
|
||||
// CHECK: @_ZTIc = constant
|
||||
// CHECK: @_ZTIPc = constant
|
||||
// CHECK: @_ZTIPKc = constant
|
||||
// CHECK: @_ZTIb = constant
|
||||
// CHECK: @_ZTIPb = constant
|
||||
// CHECK: @_ZTIPKb = constant
|
||||
// CHECK: @_ZTIa = constant
|
||||
// CHECK: @_ZTIPa = constant
|
||||
// CHECK: @_ZTIPKa = constant
|
||||
|
|
|
@ -11,13 +11,16 @@
|
|||
|
||||
|
||||
|
||||
// CHECK: _ZTI1A = weak_odr constant
|
||||
// CHECK: _ZTI1A = weak_odr hidden constant
|
||||
// CHECK: _ZTI1B = constant
|
||||
// CHECK: _ZTI1C = internal constant
|
||||
// CHECK: _ZTIA10_i = weak_odr constant
|
||||
// CHECK: _ZTI1TILj0EE = weak_odr hidden constant
|
||||
// CHECK: _ZTI1TILj1EE = weak_odr constant
|
||||
// CHECK: _ZTI1TILj2EE = external constant
|
||||
// CHECK: _ZTIA10_i = weak_odr hidden constant
|
||||
// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
|
||||
// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
|
||||
// CHECK: _ZTIFvvE = weak_odr
|
||||
// CHECK: _ZTIFvvE = weak_odr hidden constant
|
||||
// CHECK: _ZTIM1A1C = internal constant
|
||||
// CHECK: _ZTIM1AP1C = internal constant
|
||||
// CHECK: _ZTIM1CPS_ = internal constant
|
||||
|
@ -26,7 +29,7 @@
|
|||
// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
|
||||
// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
|
||||
// CHECK: _ZTIP1C = internal constant
|
||||
// CHECK: _ZTIPFvvE = weak_odr constant
|
||||
// CHECK: _ZTIPFvvE = weak_odr hidden constant
|
||||
// CHECK: _ZTIPM1Ci = internal constant
|
||||
// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
|
||||
// CHECK: _ZTIPP1C = internal constant
|
||||
|
@ -118,3 +121,14 @@ namespace Arrays {
|
|||
return typeid(A::a);
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned N> class T {
|
||||
virtual void anchor() {}
|
||||
};
|
||||
template class T<1>;
|
||||
template <> class T<2> { virtual void anchor(); };
|
||||
void t3() {
|
||||
(void) typeid(T<0>);
|
||||
(void) typeid(T<1>);
|
||||
(void) typeid(T<2>);
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ void use_F() {
|
|||
// and hidden visibility (rdar://problem/7523229).
|
||||
// CHECK-2: @_ZTV1C = weak_odr hidden constant
|
||||
// CHECK-2: @_ZTS1C = weak_odr constant
|
||||
// CHECK-2: @_ZTI1C = weak_odr constant
|
||||
// CHECK-2: @_ZTI1C = weak_odr hidden constant
|
||||
|
||||
// D has a key function that is defined in this translation unit so its vtable is
|
||||
// defined in the translation unit.
|
||||
|
@ -140,7 +140,7 @@ void use_F() {
|
|||
// so its vtable should have weak_odr linkage and hidden visibility.
|
||||
// CHECK-8: @_ZTV1FIlE = weak_odr hidden constant
|
||||
// CHECK-8: @_ZTS1FIlE = weak_odr constant
|
||||
// CHECK-8: @_ZTI1FIlE = weak_odr constant
|
||||
// CHECK-8: @_ZTI1FIlE = weak_odr hidden constant
|
||||
|
||||
// F<int> is an explicit template instantiation declaration without a
|
||||
// key function, so its vtable should have external linkage.
|
||||
|
@ -167,7 +167,7 @@ void use_F() {
|
|||
// its vtable should have weak_odr linkage and hidden visibility.
|
||||
// CHECK-13: @_ZTV1FIcE = weak_odr hidden constant
|
||||
// CHECK-13: @_ZTS1FIcE = weak_odr constant
|
||||
// CHECK-13: @_ZTI1FIcE = weak_odr constant
|
||||
// CHECK-13: @_ZTI1FIcE = weak_odr hidden constant
|
||||
|
||||
// RUN: FileCheck --check-prefix=CHECK-G %s < %t
|
||||
//
|
||||
|
|
|
@ -7,6 +7,6 @@ struct X { };
|
|||
|
||||
void f() {
|
||||
// CHECK: @_ZTS1X = weak_odr constant
|
||||
// CHECK: @_ZTI1X = weak_odr constant
|
||||
// CHECK: @_ZTI1X = weak_odr hidden constant
|
||||
(void)typeid(X&);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче