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,
// 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)
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) {
--- /dev/null
+// 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) = ^{};