]> granicus.if.org Git - clang/commitdiff
[cfi] Fix missing !type annotation.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Mon, 31 Oct 2016 22:28:10 +0000 (22:28 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Mon, 31 Oct 2016 22:28:10 +0000 (22:28 +0000)
CFI (only in the cross-dso mode) fails to set !type annotations when
a function is used before it is defined.

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

lib/CodeGen/CodeGenModule.cpp
test/CodeGen/cfi-icall-cross-dso2.c [new file with mode: 0644]

index 81d9ead3d168e1e0418bdf1e1b3e3bf525671851..291ff8ed57befeeaa5f105dc74167c5f5a1e55f8 100644 (file)
@@ -929,6 +929,11 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
     if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
       F->setAlignment(2);
   }
+
+  // In the cross-dso CFI mode, we want !type attributes on definitions only.
+  if (CodeGenOpts.SanitizeCfiCrossDso)
+    if (auto *FD = dyn_cast<FunctionDecl>(D))
+      CreateFunctionTypeMetadata(FD, F);
 }
 
 void CodeGenModule::SetCommonAttributes(const Decl *D,
@@ -1011,10 +1016,6 @@ void CodeGenModule::CreateFunctionTypeMetadata(const FunctionDecl *FD,
 
   // Additionally, if building with cross-DSO support...
   if (CodeGenOpts.SanitizeCfiCrossDso) {
-    // Don't emit entries for function declarations. In cross-DSO mode these are
-    // handled with better precision at run time.
-    if (!FD->hasBody())
-      return;
     // Skip available_externally functions. They won't be codegen'ed in the
     // current module anyway.
     if (getContext().GetGVALinkageForFunction(FD) == GVA_AvailableExternally)
@@ -1087,7 +1088,10 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
     if (MD->isVirtual())
       F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
-  CreateFunctionTypeMetadata(FD, F);
+  // Don't emit entries for function declarations in the cross-DSO mode. This
+  // is handled with better precision by the receiving DSO.
+  if (!CodeGenOpts.SanitizeCfiCrossDso)
+    CreateFunctionTypeMetadata(FD, F);
 }
 
 void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) {
diff --git a/test/CodeGen/cfi-icall-cross-dso2.c b/test/CodeGen/cfi-icall-cross-dso2.c
new file mode 100644 (file)
index 0000000..acc72a7
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -O1 -fblocks \
+// RUN:   -fsanitize=cfi-icall -fsanitize-cfi-cross-dso \
+// RUN:   -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define void @f() {{.*}} !type !{{.*}} !type !{{.*}}
+void f(void);
+void (*pf)(void) = f;
+void f(void) { }
+
+// Check that we do not crash on non-FunctionDecl definitions.
+void (^g)(void) = ^{};