diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 3b64be7a477d..e0c508463a95 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3267,8 +3267,12 @@ void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD, void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase *CB) { - // Only if needed for call graph section and only for indirect calls. - if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall()) + // Only if needed for call graph section and only for indirect calls that are + // visible externally. + // TODO: Handle local linkage symbols so they are not left out of call graph + // reducing precision. + if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall() || + !isExternallyVisible(QT->getLinkage())) return; llvm::Metadata *TypeIdMD = CreateMetadataIdentifierGeneralized(QT); diff --git a/clang/test/CodeGen/call-graph-section-internal.cpp b/clang/test/CodeGen/call-graph-section-internal.cpp new file mode 100644 index 000000000000..aea48675dfa2 --- /dev/null +++ b/clang/test/CodeGen/call-graph-section-internal.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fexperimental-call-graph-section -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s + +// Check that we do not generate callee_type metadata for indirect calls +// to functions with internal linkage (e.g., types in anonymous namespaces), +// as their type metadata identifiers are distinct MDNodes instead of +// generalized strings, which would fail the LLVM Verifier. + +namespace { +class a; +class b { +public: + virtual void c(a); +}; +class a { +public: + b &e; + void d() { e.c(*this); } +}; + +void b::c(a) {} + +void f() { + a *g = nullptr; + g->d(); +} +} // namespace + +void test() { + f(); +} + +// CHECK-LABEL: define {{.*}} void @{{.*}}1a1dEv +// CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %{{.*}}, i{{[0-9]+}} 0 +// CHECK: %[[FP:.*]] = load ptr, ptr %[[VFN]], align {{[0-9]+}} +// CHECK: call void %[[FP]]({{.*}}) +// CHECK-NOT: !callee_type +// CHECK: ret void