Index: lib/IR/TypeFinder.cpp =================================================================== --- lib/IR/TypeFinder.cpp +++ lib/IR/TypeFinder.cpp @@ -47,13 +47,19 @@ } // Get types from functions. - SmallVector, 4> MDForInst; + SmallVector, 4> MDs; for (const Function &FI : M) { incorporateType(FI.getType()); for (const Use &U : FI.operands()) incorporateValue(U.get()); + // Incorporate types hiding in metadata. + FI.getAllMetadata(MDs); + for (const auto &MD : MDs) + incorporateMDNode(MD.second); + MDs.clear(); + // First incorporate the arguments. for (const auto &A : FI.args()) incorporateValue(&A); @@ -70,10 +76,10 @@ incorporateValue(&*O); // Incorporate types hiding in metadata. - I.getAllMetadataOtherThanDebugLoc(MDForInst); - for (const auto &MD : MDForInst) + I.getAllMetadataOtherThanDebugLoc(MDs); + for (const auto &MD : MDs) incorporateMDNode(MD.second); - MDForInst.clear(); + MDs.clear(); } } Index: unittests/IR/CMakeLists.txt =================================================================== --- unittests/IR/CMakeLists.txt +++ unittests/IR/CMakeLists.txt @@ -31,6 +31,7 @@ PassManagerTest.cpp PatternMatch.cpp TypeBuilderTest.cpp + TypeFinderTest.cpp TypesTest.cpp UseTest.cpp UserTest.cpp Index: unittests/IR/TypeFinderTest.cpp =================================================================== --- /dev/null +++ unittests/IR/TypeFinderTest.cpp @@ -0,0 +1,43 @@ +//===- llvm/unittest/IR/TypeFinderTest.cpp - TypeFinder unit tests --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/TypeFinder.h" + +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace llvm; +using ::testing::UnorderedElementsAre; + +namespace { + +TEST(TypeFinderTest, FunctionMetadata) { + LLVMContext C; + + // PR39237 + Module M("Test", C); + Function *F = cast(M.getOrInsertFunction( + "foo", FunctionType::get(Type::getVoidTy(C), None, false))); + StructType *Struct = StructType::create(C, "FooBar"); + Metadata *Value = ConstantAsMetadata::get(ConstantAggregateZero::get(Struct)); + MDNode *Node = MDNode::get(C, Value); + F->setMetadata("bar", Node); + + TypeFinder Finder; + Finder.run(M, /*onlyNamed*/ false); + EXPECT_THAT(Finder, UnorderedElementsAre(Struct)); +} + +} // end anonymous namespace