]> granicus.if.org Git - clang/commitdiff
[ubsan] Don't emit function signatures for non-static member functions
authorVedant Kumar <vsk@apple.com>
Sat, 14 Oct 2017 01:23:30 +0000 (01:23 +0000)
committerVedant Kumar <vsk@apple.com>
Sat, 14 Oct 2017 01:23:30 +0000 (01:23 +0000)
The function sanitizer only checks indirect calls through function
pointers. This excludes all non-static member functions (constructor
calls, calls through thunks, etc. all use a separate code path). Don't
emit function signatures for functions that won't be checked.

Apart from cutting down on code size, this should fix a regression on
Linux caused by r313096. For context, see the mailing list discussion:

r313096 - [ubsan] Function Sanitizer: Don't require writable text segments

Testing: check-clang, check-ubsan

Differential Revision: https://reviews.llvm.org/D38913

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315786 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenFunction.cpp
test/CodeGenCXX/catch-undef-behavior.cpp

index 26df45f5350ff0e46c4e2491cf80ffb215527b37..aac603c104d96b0766e79e69a2e31c773adcf07e 100644 (file)
@@ -789,6 +789,15 @@ static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) {
   return true;
 }
 
+/// Return the UBSan prologue signature for \p FD if one is available.
+static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
+                                            const FunctionDecl *FD) {
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
+    if (!MD->isStatic())
+      return nullptr;
+  return CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM);
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
@@ -908,8 +917,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
   // prologue data.
   if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {
     if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
-      if (llvm::Constant *PrologueSig =
-              CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
+      if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) {
         llvm::Constant *FTRTTIConst =
             CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true);
         llvm::Constant *FTRTTIConstEncoded =
index aa3da1071dda4a45d662bfe4b77da24f87aeb624..e8287538982b8d4c1878ee4e81c3f194288fe789 100644 (file)
@@ -426,6 +426,66 @@ void indirect_function_call(void (*p)(int)) {
   p(42);
 }
 
+namespace FunctionSanitizerVirtualCalls {
+struct A {
+  virtual void f() {}
+  virtual void g() {}
+  void h() {}
+};
+
+struct B : virtual A {
+  virtual void b() {}
+  virtual void f();
+  void g() final {}
+  static void q() {}
+};
+
+void B::f() {}
+
+void force_irgen() {
+  A a;
+  a.g();
+  a.h();
+
+  B b;
+  b.f();
+  b.b();
+  b.g();
+  B::q();
+}
+
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv()
+// CHECK: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv
+// CHECK: prologue
+
+}
+
 namespace UpcastPointerTest {
 struct S {};
 struct T : S { double d; };