diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index 333ce033f..63a913eea 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -162,7 +162,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { } [[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel( - llvm::Module &M, llvm::ArrayRef UserEntryPoints); + LLVMProjectIRDB &IRDB, llvm::ArrayRef UserEntryPoints); void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver, llvm::ArrayRef EntryPoints, Soundness S, diff --git a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h index ba92829e5..3e255c2fc 100644 --- a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h +++ b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h @@ -22,9 +22,9 @@ struct FunctionData { std::string Name; TaintCategory ReturnCat{}; - std::vector SourceValues; - std::vector SinkValues; - std::vector SanitizerValues; + std::vector SourceValues{}; + std::vector SinkValues{}; + std::vector SanitizerValues{}; bool HasAllSinkParam = false; }; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp index 74e8a9716..d1c9aca22 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp @@ -106,7 +106,8 @@ static bool fillPossibleTargets( Resolver::FunctionSetTy &PossibleTargets, Resolver &Res, const llvm::CallBase *CS, llvm::DenseMap &IndirectCalls) { - if (const auto *StaticCallee = CS->getCalledFunction()) { + if (const auto *StaticCallee = llvm::dyn_cast( + CS->getCalledOperand()->stripPointerCastsAndAliases())) { PossibleTargets.insert(StaticCallee); PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", @@ -115,16 +116,7 @@ static bool fillPossibleTargets( return true; } - // still try to resolve the called function statically - const llvm::Value *SV = CS->getCalledOperand()->stripPointerCastsAndAliases(); - if (const auto *ValueFunction = llvm::dyn_cast(SV)) { - PossibleTargets.insert(ValueFunction); - PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found static call-site: " << llvmIRToString(CS)); - return true; - } - - if (llvm::isa(SV)) { + if (llvm::isa(CS->getCalledOperand())) { return true; } diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index 23dbdcc28..62872851b 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -146,10 +146,12 @@ LLVMTypeHierarchy::removeStructOrClassPrefix(const llvm::StructType &T) { std::string LLVMTypeHierarchy::removeStructOrClassPrefix(llvm::StringRef TypeName) { if (TypeName.startswith(StructPrefix)) { - return TypeName.drop_front(StructPrefix.size()).str(); + TypeName = TypeName.drop_front(StructPrefix.size()); + } else if (TypeName.startswith(ClassPrefix)) { + TypeName = TypeName.drop_front(ClassPrefix.size()); } - if (TypeName.startswith(ClassPrefix)) { - return TypeName.drop_front(ClassPrefix.size()).str(); + if (TypeName.endswith(".base")) { + TypeName = TypeName.drop_back(llvm::StringRef(".base").size()); } return TypeName.str(); } @@ -231,18 +233,15 @@ LLVMTypeHierarchy::getSubTypes(const llvm::Module & /*M*/, if (const auto *I = llvm::dyn_cast(TI->getInitializer())) { for (const auto &Op : I->operands()) { - if (auto *CE = llvm::dyn_cast(Op)) { - if (auto *BC = llvm::dyn_cast(CE)) { - if (BC->getOperand(0)->hasName()) { - auto Name = BC->getOperand(0)->getName(); - if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { - auto ClearName = - removeTypeInfoPrefix(llvm::demangle(Name.str())); - if (auto TypeIt = ClearNameTypeMap.find(ClearName); - TypeIt != ClearNameTypeMap.end()) { - SubTypes.push_back(TypeIt->second); - } - } + const auto *CE = Op->stripPointerCastsAndAliases(); + + if (CE->hasName()) { + auto Name = CE->getName(); + if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { + auto ClearName = removeTypeInfoPrefix(llvm::demangle(Name.str())); + if (auto TypeIt = ClearNameTypeMap.find(ClearName); + TypeIt != ClearNameTypeMap.end()) { + SubTypes.push_back(TypeIt->second); } } } @@ -329,8 +328,9 @@ LLVMTypeHierarchy::getSubTypes(const llvm::StructType *Type) const { return {}; } -const llvm::StructType * -LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { +template +static const llvm::StructType *getTypeImpl(const GraphT &TypeGraph, + llvm::StringRef TypeName) { for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { if (TypeGraph[V].Type->getName() == TypeName) { return TypeGraph[V].Type; @@ -339,6 +339,17 @@ LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { return nullptr; } +const llvm::StructType * +LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { + if (const auto *Ty = getTypeImpl(TypeGraph, TypeName)) { + return Ty; + } + + // Sometimes, clang adds a .base suffix + std::string TN = TypeName.str() + ".base"; + return getTypeImpl(TypeGraph, TypeName); +} + std::vector LLVMTypeHierarchy::getAllTypes() const { std::vector Types; Types.reserve(boost::num_vertices(TypeGraph)); diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index 2b6b443ef..b25822da8 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -82,22 +82,10 @@ LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT) { // is RTTI for (const auto *It = std::next(CA->operands().begin(), 2); It != CA->operands().end(); ++It) { - const auto &COp = *It; - if (const auto *CE = llvm::dyn_cast(COp)) { - if (const auto *BC = llvm::dyn_cast(CE)) { - // if the entry is a GlobalAlias, get its Aliasee - auto *Entry = BC->getOperand(0); - while (auto *GA = llvm::dyn_cast(Entry)) { - Entry = GA->getAliasee(); - } - auto *F = llvm::dyn_cast(Entry); - VFS.push_back(F); - } else { - VFS.push_back(nullptr); - } - } else { - VFS.push_back(nullptr); - } + const auto *Entry = It->get()->stripPointerCastsAndAliases(); + + const auto *F = llvm::dyn_cast(Entry); + VFS.push_back(F); } } } diff --git a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp index 0fa9a40bd..e8d700cf6 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp +++ b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp @@ -27,8 +27,9 @@ TEST(LTHTest, BasicTHReconstruction_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "type_hierarchies/type_hierarchy_1_cpp.ll"); LLVMTypeHierarchy LTH(IRDB); - EXPECT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); - EXPECT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); + + ASSERT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); + ASSERT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); EXPECT_EQ(LTH.getAllTypes().size(), 2U); EXPECT_EQ( LTH.isSubType(LTH.getType("struct.Base"), LTH.getType("struct.Child")), @@ -163,12 +164,10 @@ TEST(LTHTest, BasicTHReconstruction_7) { LLVMTypeHierarchy LTH(IRDB); EXPECT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); EXPECT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); - // has three types because of padding (introduction of intermediate type) EXPECT_EQ(LTH.getAllTypes().size(), 3U); EXPECT_EQ( LTH.isSubType(LTH.getType("struct.Base"), LTH.getType("struct.Child")), true); - EXPECT_EQ(LTH.getSubTypes(LTH.getType("struct.Base")).size(), 2U); EXPECT_EQ(LTH.getSubTypes(LTH.getType("struct.Child")).size(), 1U); auto BaseReachable = LTH.getSubTypes(LTH.getType("struct.Base")); @@ -268,7 +267,6 @@ TEST(LTHTest, TransitivelyReachableTypes) { ASSERT_TRUE(ReachableTypesNonvirtualstruct3.size() == 1U); ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Base"))); - ASSERT_FALSE(ReachableTypesBase4.count(TH4.getType("struct.Base.base"))); ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Child"))); ASSERT_TRUE(ReachableTypesBase4.size() == 2U); ASSERT_TRUE(ReachableTypesChild4.count(TH4.getType("struct.Child")));