r269089 - Introduce CGCXXABI::canCallMismatchedFunctionType

Derek Schuff via cfe-commits cfe-commits at lists.llvm.org
Tue May 10 10:44:55 PDT 2016


Author: dschuff
Date: Tue May 10 12:44:55 2016
New Revision: 269089

URL: http://llvm.org/viewvc/llvm-project?rev=269089&view=rev
Log:
Introduce CGCXXABI::canCallMismatchedFunctionType

Modified:
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/runtimecc.cpp
    cfe/trunk/test/CodeGenCXX/static-destructor.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=269089&r1=269088&r2=269089&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue May 10 12:44:55 2016
@@ -106,6 +106,16 @@ public:
 
   virtual bool hasMostDerivedReturn(GlobalDecl GD) const { return false; }
 
+  /// Returns true if the target allows calling a function through a pointer
+  /// with a different signature than the actual function (or equivalently,
+  /// bitcasting a function or function pointer to a different function type).
+  /// In principle in the most general case this could depend on the target, the
+  /// calling convention, and the actual types of the arguments and return
+  /// value. Here it just means whether the signature mismatch could *ever* be
+  /// allowed; in other words, does the target do strict checking of signatures
+  /// for all calls.
+  virtual bool canCallMismatchedFunctionType() const { return true; }
+
   /// If the C++ ABI requires the given type be returned in a particular way,
   /// this method sets RetAI and returns true.
   virtual bool classifyReturnType(CGFunctionInfo &FI) const = 0;

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=269089&r1=269088&r2=269089&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Tue May 10 12:44:55 2016
@@ -88,11 +88,12 @@ static void EmitDeclDestroy(CodeGenFunct
 
   // Special-case non-array C++ destructors, if they have the right signature.
   // Under some ABIs, destructors return this instead of void, and cannot be
-  // passed directly to __cxa_atexit.
+  // passed directly to __cxa_atexit if the target does not allow this mismatch.
   const CXXRecordDecl *Record = type->getAsCXXRecordDecl();
-  bool CanRegisterDestructor = Record &&
-                               !CGM.getCXXABI().HasThisReturn(GlobalDecl(
-                                   Record->getDestructor(), Dtor_Complete));
+  bool CanRegisterDestructor =
+      Record && (!CGM.getCXXABI().HasThisReturn(
+                     GlobalDecl(Record->getDestructor(), Dtor_Complete)) ||
+                 CGM.getCXXABI().canCallMismatchedFunctionType());
   // If __cxa_atexit is disabled via a flag, a different helper function is
   // generated elsewhere which uses atexit instead, and it takes the destructor
   // directly.

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=269089&r1=269088&r2=269089&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue May 10 12:44:55 2016
@@ -443,6 +443,7 @@ private:
            (isa<CXXDestructorDecl>(GD.getDecl()) &&
             GD.getDtorType() != Dtor_Deleting);
   }
+  bool canCallMismatchedFunctionType() const override { return false; }
 };
 }
 

Modified: cfe/trunk/test/CodeGenCXX/runtimecc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/runtimecc.cpp?rev=269089&r1=269088&r2=269089&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/runtimecc.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/runtimecc.cpp Tue May 10 12:44:55 2016
@@ -22,13 +22,8 @@ namespace test0 {
   A global;
 // CHECK-LABEL:    define internal void @__cxx_global_var_init()
 // CHECK:      call [[A]]* @_ZN5test01AC1Ev([[A]]* @_ZN5test06globalE)
-// CHECK-NEXT: call i32 @__cxa_atexit(void (i8*)* @__cxx_global_array_dtor, i8* null, i8* @__dso_handle) [[NOUNWIND:#[0-9]+]]
+// CHECK-NEXT: call i32 @__cxa_atexit(void (i8*)* bitcast ([[A]]* ([[A]]*)* @_ZN5test01AD1Ev to void (i8*)*), i8* bitcast ([[A]]* @_ZN5test06globalE to i8*), i8* @__dso_handle) [[NOUNWIND:#[0-9]+]]
 // CHECK-NEXT: ret void
-
-// CHECK-LABEL: define internal void @__cxx_global_array_dtor(i8*)
-// CHECK: call [[A]]* @_ZN5test01AD1Ev([[A]]* @_ZN5test06globalE)
-// CHECK-NEXT: ret void
-
 }
 
 // CHECK: declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) [[NOUNWIND]]

Modified: cfe/trunk/test/CodeGenCXX/static-destructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/static-destructor.cpp?rev=269089&r1=269088&r2=269089&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/static-destructor.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/static-destructor.cpp Tue May 10 12:44:55 2016
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=X86 %s
 // RUN: %clang_cc1 %s -triple=wasm32 -emit-llvm -o - | FileCheck --check-prefix=WASM %s
-// RUN: %clang_cc1 %s -triple=armv7-apple-darwin9 -emit-llvm -o - | FileCheck --check-prefix=WASM %s
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin9 -emit-llvm -o - | FileCheck --check-prefix=ARM %s
 
 // Test that destructors are not passed directly to __cxa_atexit when their
 // signatures do not match the type of its first argument.
@@ -20,6 +20,12 @@ Foo global;
 // X86-NEXT: entry:
 // X86-NEXT:   %0 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
 
+// ARM destructors return this, but can be registered directly with __cxa_atexit
+// because the calling conventions tolerate the mismatch.
+// ARM: define internal void @__cxx_global_var_init()
+// ARM-NEXT: entry:
+// ARM-NEXT:   %0 = call i32 @__cxa_atexit(void (i8*)* bitcast (%class.Foo* (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
+
 // Wasm destructors return this, and use a wrapper function, which is registered
 // with __cxa_atexit.
 // WASM: define internal void @__cxx_global_var_init()




More information about the cfe-commits mailing list