Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -782,6 +782,21 @@ } } + // Ignore unrelated casts from C++ calls to allocate(). Don't match on the + // namespace because not all allocators are in std:: + if (D && SanOpts.has(SanitizerKind::CFIUnrelatedCast)) { + auto *MD = dyn_cast_or_null(D); + if (MD && MD->getName().equals("allocate") && MD->getNumParams() == 2) { + auto *BT = MD->parameters()[0]->getType()->getAs(); + auto *PT = MD->parameters()[1]->getType()->getAs(); + if (BT && PT && PT->isVoidPointerType() && + PT->getPointeeType().isConstQualified() && + (BT->getKind() == BuiltinType::UInt || + BT->getKind() == BuiltinType::ULong)) + SanOpts.Mask &= ~SanitizerKind::CFIUnrelatedCast; + } + } + // Apply xray attributes to the function (as a string, for now) if (D && ShouldXRayInstrumentFunction()) { if (const auto *XRayAttr = D->getAttr()) { Index: test/CodeGen/cfi-unrelated-cast.cpp =================================================================== --- /dev/null +++ test/CodeGen/cfi-unrelated-cast.cpp @@ -0,0 +1,32 @@ +// STL allocators should not have unrelated-cast tests applied +// RUN: %clang_cc1 -flto -fvisibility hidden -fsanitize=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck %s + +template +class myalloc { + public: + // CHECK: define{{.*}}allocate + // CHECK-NOT: llvm.type.test + T *allocate(unsigned int sz, const void *ptr = 0) { + return (T*)ptr; + } + + // CHECK: define{{.*}}differentName + // CHECK: llvm.type.test + T *differentName(unsigned int sz, const void *ptr = 0) { + return (T*)ptr; + } +}; + +class C1 { + virtual void f() {} +}; + +C1 *f1() { + myalloc allocator; + return allocator.allocate(16); +} + +C1 *f2() { + myalloc allocator; + return allocator.differentName(16); +}