r246214 - Assume loads fix #2

Steven Wu via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 28 00:16:33 PDT 2015


I am pretty sure this commit and r246213 causes llvm LTO bootstrap to hang in ScalarEvolution. Doesn’t look like a bug introduced in the commit but definitely triggered something bad. I reverted both commit in r246282.

You should able to reproduce the hang by building llvm-cov using LTO. Let me know if you need help for a reduced test case.

Thanks

Steven

> On Aug 27, 2015, at 2:35 PM, Piotr Padlewski via cfe-commits <cfe-commits at lists.llvm.org> wrote:
> 
> Author: prazek
> Date: Thu Aug 27 16:35:41 2015
> New Revision: 246214
> 
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D246214-26view-3Drev&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=bzaEvH1N-pXVZNnhTXbVnUXyKmR20AciXN_zJ-SETjw&e= 
> Log:
> Assume loads fix #2
> 
> There was linker problem, and it turns out that it is not always safe
> to refer to vtable. If the vtable is used, then we can refer to it
> without any problem, but because we don't know when it will be used or
> not, we can only check if vtable is external or it is safe to to emit it
> speculativly (when class it doesn't have any inline virtual functions).
> It should be fixed in the future.
> 
> https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D12385&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=bMLQH3JdjE2Utt9cC3cfAJOSJ05ZaOoTW7ev_hDFEgQ&e= 
> 
> Modified:
>    cfe/trunk/lib/CodeGen/CGCXXABI.h
>    cfe/trunk/lib/CodeGen/CGClass.cpp
>    cfe/trunk/lib/CodeGen/CGVTables.cpp
>    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>    cfe/trunk/test/CodeGenCXX/template-instantiation.cpp
>    cfe/trunk/test/CodeGenCXX/thunks.cpp
>    cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp
>    cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp
> 
> Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGCXXABI.h-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=leudiFW4SvRTkcpIUEbGg8vvviVI12BygT3LQphKTBc&e= 
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
> +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Thu Aug 27 16:35:41 2015
> @@ -218,8 +218,10 @@ public:
>   virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) = 0;
>   virtual llvm::GlobalVariable *getThrowInfo(QualType T) { return nullptr; }
> 
> -  virtual bool canEmitAvailableExternallyVTable(
> -      const CXXRecordDecl *RD) const = 0;
> +  /// \brief Determine whether it's possible to emit a vtable for \p RD, even
> +  /// though we do not know that the vtable has been marked as used by semantic
> +  /// analysis.
> +  virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const = 0;
> 
>   virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) = 0;
> 
> 
> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGClass.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=pjy3fMgGIh-biMJxLcTXYSklw13ul6gAje-Ft1LgxQg&e= 
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Aug 27 16:35:41 2015
> @@ -1857,8 +1857,15 @@ void CodeGenFunction::EmitCXXConstructor
>   // with a vtable.  We don't do this for base subobjects for two reasons:
>   // first, it's incorrect for classes with virtual bases, and second, we're
>   // about to overwrite the vptrs anyway.
> +  // We also have to make sure if we can refer to vtable:
> +  // - If vtable is external then it's safe to use it (for available_externally
> +  //   CGVTables will make sure if it can emit it).
> +  // - Otherwise we can refer to vtable if it's safe to speculatively emit.
> +  // FIXME: If vtable is used by ctor/dtor, we are always safe to refer to it.
>   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
> -      ClassDecl->isDynamicClass() && Type != Ctor_Base)
> +      ClassDecl->isDynamicClass() && Type != Ctor_Base &&
> +      (CGM.getVTables().isVTableExternal(ClassDecl) ||
> +       CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl)))
>     EmitVTableAssumptionLoads(ClassDecl, This);
> }
> 
> 
> Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGVTables.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=g7Lu0-698j2gOLjenkl742wJk_FfvrXdWEvvkcYnlZg&e= 
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Thu Aug 27 16:35:41 2015
> @@ -682,7 +682,7 @@ CodeGenVTables::GenerateConstructionVTab
> static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
>                                                 const CXXRecordDecl *RD) {
>   return CGM.getCodeGenOpts().OptimizationLevel > 0 &&
> -            CGM.getCXXABI().canEmitAvailableExternallyVTable(RD);
> +            CGM.getCXXABI().canSpeculativelyEmitVTable(RD);
> }
> 
> /// Compute the required linkage of the v-table for the given class.
> @@ -832,11 +832,11 @@ bool CodeGenVTables::isVTableExternal(co
> /// we define that v-table?
> static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
>                                                    const CXXRecordDecl *RD) {
> -  // If vtable is internal then it has to be done
> +  // If vtable is internal then it has to be done.
>   if (!CGM.getVTables().isVTableExternal(RD))
>     return true;
> 
> -  // If it's external then maybe we will need it as available_externally
> +  // If it's external then maybe we will need it as available_externally.
>   return shouldEmitAvailableExternallyVTable(CGM, RD);
> }
> 
> 
> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_ItaniumCXXABI.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=6SgmhWexe_OrWV7QSHifL8Qfy_0nzGZqwIL20CMdL18&e= 
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Aug 27 16:35:41 2015
> @@ -229,7 +229,7 @@ public:
> 
>   void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
> 
> -  bool canEmitAvailableExternallyVTable(const CXXRecordDecl *RD) const override;
> +  bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override;
> 
>   void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,
>                        bool ReturnAdjustment) override {
> @@ -1523,8 +1523,7 @@ void ItaniumCXXABI::emitVirtualInheritan
>   VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD);
> }
> 
> -bool ItaniumCXXABI::canEmitAvailableExternallyVTable(
> -    const CXXRecordDecl *RD) const {
> +bool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const {
>   // We don't emit available_externally vtables if we are in -fapple-kext mode
>   // because kext mode does not permit devirtualization.
>   if (CGM.getLangOpts().AppleKext)
> 
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_MicrosoftCXXABI.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=k3-1pr5XAAzds0s8Dt8uQXU0wQQju5Zrpi748-rG8d4&e= 
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Aug 27 16:35:41 2015
> @@ -106,8 +106,7 @@ public:
>                                      QualType DestTy) override;
> 
>   bool EmitBadCastCall(CodeGenFunction &CGF) override;
> -  bool canEmitAvailableExternallyVTable(
> -      const CXXRecordDecl *RD) const override {
> +  bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override {
>     return false;
>   }
> 
> 
> Modified: cfe/trunk/test/CodeGenCXX/template-instantiation.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_template-2Dinstantiation.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=oV1Fn11pOf5WWQXsUc5vOoyFIjrYUoxRIrzwloJkd7M&e= 
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/template-instantiation.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/template-instantiation.cpp Thu Aug 27 16:35:41 2015
> @@ -1,7 +1,5 @@
> // RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
> 
> -// CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
> -
> // CHECK: @_ZN7PR100011xE = global
> // CHECK-NOT: @_ZN7PR100014kBarE = external global i32
> //
> @@ -14,6 +12,7 @@
> // CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
> // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A
> 
> +// CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
> 
> // CHECK-NOT: _ZTVN5test31SIiEE
> // CHECK-NOT: _ZTSN5test31SIiEE
> 
> Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_thunks.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=HOj_pgWtDkr-TjGjqGJ74fuhEJvJ-hERLQexS5WesNo&e= 
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/thunks.cpp Thu Aug 27 16:35:41 2015
> @@ -398,11 +398,13 @@ D::~D() {}
> // Checking with opt
> // CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #0 align 2
> 
> +// This is from Test5:
> +// CHECK-OPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
> +
> // This is from Test10:
> // CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
> // CHECK-OPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
> 
> -// This is from Test5:
> -// CHECK-OPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
> +
> 
> // CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} }
> 
> Modified: cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_vtable-2Dassume-2Dload.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=aoONH-TAokcCxgBc1rV9R-r86VigUYnsH9XW94YZ3AM&e= 
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp Thu Aug 27 16:35:41 2015
> @@ -6,7 +6,9 @@
> // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
> // RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
> // RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
> -
> +// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
> +// RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
> +// RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
> namespace test1 {
> 
> struct A {
> @@ -150,7 +152,7 @@ void test() {
> }
> } // test4
> 
> -namespace test5 {
> +namespace testMS {
> 
> struct __declspec(novtable) S {
>   virtual void foo();
> @@ -159,8 +161,8 @@ struct __declspec(novtable) S {
> void g(S &s) { s.foo(); }
> 
> // if struct has novtable specifier, then we can't generate assumes
> -// CHECK-MS-LABEL: define void @"\01?test at test5@@YAXXZ"()
> -// CHECK-MS: call x86_thiscallcc %"struct.test5::S"* @"\01??0S at test5@@QAE at XZ"(
> +// CHECK-MS-LABEL: define void @"\01?test at testMS@@YAXXZ"()
> +// CHECK-MS: call x86_thiscallcc %"struct.testMS::S"* @"\01??0S at testMS@@QAE at XZ"(
> // CHECK-MS-NOT: @llvm.assume
> // CHECK-MS-LABEL: }
> 
> @@ -169,4 +171,125 @@ void test() {
>   g(s);
> }
> 
> -} // test5
> +} // testMS
> +
> +namespace test6 {
> +// CHECK6: @_ZTVN5test61AE = external
> +struct A {
> +  A();
> +  virtual void foo();
> +  virtual ~A() {}
> +};
> +struct B : A {
> +  B();
> +};
> +// Because A's vtable is external, it's safe to generate assumption loads.
> +// CHECK6-LABEL: define void @_ZN5test61gEv()
> +// CHECK6: call void @_ZN5test61AC1Ev(
> +// CHECK6: call void @llvm.assume(
> +
> +// We can't emit assumption loads for B, because if we would refer to vtable
> +// it would refer to functions that will not be able to find (like implicit
> +// inline destructor).
> +
> +// CHECK6-LABEL:   call void @_ZN5test61BC1Ev(
> +// CHECK6-NOT: call void @llvm.assume(
> +// CHECK6-LABEL: }
> +void g() {
> +  A *a = new A;
> +  B *b = new B;
> +}
> +
> +}
> +
> +namespace test7 {
> +// Because A's key function is defined here, vtable is generated in this TU
> +// CHECK7: @_ZTVN5test71AE = unnamed_addr constant
> +struct A {
> +  A();
> +  virtual void foo();
> +  virtual void bar();
> +};
> +void A::foo() {}
> +
> +// CHECK7-LABEL: define void @_ZN5test71gEv()
> +// CHECK7: call void @_ZN5test71AC1Ev(
> +// CHECK7: call void @llvm.assume(
> +// CHECK7-LABEL: }
> +void g() {
> +  A *a = new A();
> +  a->bar();
> +}
> +}
> +
> +namespace test8 {
> +
> +struct A {
> +  virtual void foo();
> +  virtual void bar();
> +};
> +
> +// CHECK8-DAG: @_ZTVN5test81BE = available_externally unnamed_addr constant
> +struct B : A {
> +  B();
> +  void foo();
> +  void bar();
> +};
> +
> +// CHECK8-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr constant
> +struct C : A {
> +  C();
> +  void bar();
> +  void foo() {}
> +};
> +inline void C::bar() {}
> +
> +// CHECK8-DAG: @_ZTVN5test81DE = external unnamed_addr constant
> +struct D : A {
> +  D();
> +  void foo();
> +  void inline bar();
> +};
> +void D::bar() {}
> +
> +// CHECK8-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr constant
> +struct E : A {
> +  E();
> +};
> +
> +// CHECK8-LABEL: define void @_ZN5test81bEv()
> +// CHECK8: call void @llvm.assume(
> +// CHECK8-LABEL: }
> +void b() {
> +  B b;
> +  b.bar();
> +}
> +
> +// FIXME: C has inline virtual functions which prohibits as from generating
> +// assumption loads, but because vtable is generated in this TU (key function
> +// defined here) it would be correct to refer to it.
> +// CHECK8-LABEL: define void @_ZN5test81cEv()
> +// CHECK8-NOT: call void @llvm.assume(
> +// CHECK8-LABEL: }
> +void c() {
> +  C c;
> +  c.bar();
> +}
> +
> +// CHECK8-LABEL: define void @_ZN5test81dEv()
> +// CHECK8: call void @llvm.assume(
> +// CHECK8-LABEL: }
> +void d() {
> +  D d;
> +  d.bar();
> +}
> +
> +// CHECK8-LABEL: define void @_ZN5test81eEv()
> +// CHECK8: call void @llvm.assume(
> +// CHECK8-LABEL: }
> +void e() {
> +  E e;
> +  e.bar();
> +}
> +}
> +
> 
> Modified: cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp
> URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_vtable-2Davailable-2Dexternally.cpp-3Frev-3D246214-26r1-3D246213-26r2-3D246214-26view-3Ddiff&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=Cf6C7Z9I70VP5dTHGiEBzGNSco44HZeIAkYz8mo6j6U&e= 
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp Thu Aug 27 16:35:41 2015
> @@ -184,8 +184,8 @@ void f() {
> }  // Test8
> 
> namespace Test9 {
> -// all virtual functions are outline, so we can assume that it will
> -// be generated in translation unit where foo is defined
> +// All virtual functions are outline, so we can assume that it will
> +// be generated in translation unit where foo is defined.
> // CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
> // CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
> struct A {
> @@ -217,14 +217,14 @@ struct A {
> };
> void A::foo() {}
> 
> -// Because key function is inline we will generate vtable as linkonce_odr
> +// Because key function is inline we will generate vtable as linkonce_odr.
> // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
> struct D : A {
>   void bar();
> };
> inline void D::bar() {}
> 
> -// because B has outline key function then we can refer to
> +// Because B has outline all virtual functions, we can refer to them.
> // CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
> struct B : A {
>   void foo();
> @@ -233,7 +233,7 @@ struct B : A {
> 
> // C's key function (car) is outline, but C has inline virtual function so we
> // can't guarantee that we will be able to refer to bar from name
> -// so (at the moment) we can't emit vtable available_externally
> +// so (at the moment) we can't emit vtable available_externally.
> // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
> struct C : A {
>   void bar() {}               // defined in body - not key function
> @@ -365,4 +365,3 @@ void test() {
> }
> }
> 
> -
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_cfe-2Dcommits&d=BQIGaQ&c=eEvniauFctOgLOKGJOplqw&r=AyppgLQmqA6F6mGKjHYJQMsYFVSyBzNb052X2-XqxQo&m=74Ho53VBiSjPg1sSirQymG9cfu0g_kH2TPgrIwIkMsA&s=NPF5cP5ya7r7K3mox1xhAfC-APfC4NrZlhhdePo545k&e= 



More information about the cfe-commits mailing list