aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2023-05-22 10:11:30 -0700
committerFangrui Song <i@maskray.me>2023-05-22 10:11:30 -0700
commit279a4d0d67c874e80c171666822f2fabdd6fa926 (patch)
treecf47e675b15f284ca4e388773590e078646dc8b3 /clang/lib/CodeGen/CodeGenFunction.cpp
parent7b5d6cd7fcac2b9e06338f2497fed9039360924a (diff)
downloadllvm-279a4d0d67c874e80c171666822f2fabdd6fa926.zip
llvm-279a4d0d67c874e80c171666822f2fabdd6fa926.tar.gz
llvm-279a4d0d67c874e80c171666822f2fabdd6fa926.tar.bz2
-fsanitize=function: support C
With D148785, -fsanitize=function no longer uses C++ RTTI objects and therefore can support C. The rationale for reporting errors is C11 6.5.2.2p9: > If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined. The mangled types approach we use does not exactly match the C type compatibility (see `f(callee1)` below). This is probably fine as the rules are unlikely leveraged in practice. In addition, the call is warned by -Wincompatible-function-pointer-types-strict. ``` void callee0(int (*a)[]) {} void callee1(int (*a)[1]) {} void f(void (*fp)(int (*)[])) { fp(0); } int main() { int a[1]; f(callee0); f(callee1); // compatible but flagged by -fsanitize=function, -fsanitize=kcfi, and -Wincompatible-function-pointer-types-strict } ``` Skip indirect call sites of a function type without a prototype to avoid deal with C11 6.5.2.2p6. -fsanitize=kcfi skips such calls as well. Reviewed By: #sanitizers, vitalybuka Differential Revision: https://reviews.llvm.org/D148827
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp7
1 files changed, 4 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index e52c483..a0a6299 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -572,10 +572,11 @@ llvm::ConstantInt *
CodeGenFunction::getUBSanFunctionTypeHash(QualType Ty) const {
// Remove any (C++17) exception specifications, to allow calling e.g. a
// noexcept function through a non-noexcept pointer.
- auto ProtoTy = getContext().getFunctionTypeWithExceptionSpec(Ty, EST_None);
+ if (!isa<FunctionNoProtoType>(Ty))
+ Ty = getContext().getFunctionTypeWithExceptionSpec(Ty, EST_None);
std::string Mangled;
llvm::raw_string_ostream Out(Mangled);
- CGM.getCXXABI().getMangleContext().mangleTypeName(ProtoTy, Out, false);
+ CGM.getCXXABI().getMangleContext().mangleTypeName(Ty, Out, false);
return llvm::ConstantInt::get(CGM.Int32Ty,
static_cast<uint32_t>(llvm::xxHash64(Mangled)));
}
@@ -945,7 +946,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// If we are checking function types, emit a function type signature as
// prologue data.
- if (FD && getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {
+ if (FD && SanOpts.has(SanitizerKind::Function)) {
if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) {
llvm::LLVMContext &Ctx = Fn->getContext();
llvm::MDBuilder MDB(Ctx);