Skip to content

Commit 814ae82

Browse files
mxHuberfabianbs96
andauthored
Dbg-Info based Type Matching (#791)
* moved stripPointerTypes() + debug prints * MetadataKind approach * I think we don't get around using getName() * unittests still fail * bugfix + cleanup * Some cleanup * Implement allocated-types collection in terms of debug info * Fix libdeps * Remove some unneeded includes --------- Co-authored-by: Fabian Schiebel <[email protected]> Co-authored-by: Fabian Schiebel <[email protected]>
1 parent 1e857b1 commit 814ae82

18 files changed

+170
-168
lines changed

include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
1616
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
1717
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
18+
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
1819
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h"
1920
#include "phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h"
2021
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
@@ -35,9 +36,6 @@
3536

3637
namespace psr {
3738

38-
class LLVMBasedICFG;
39-
class LLVMTypeHierarchy;
40-
4139
namespace detail {
4240

4341
class IDETypeStateAnalysisBaseCommon : public LLVMAnalysisDomainDefault {
@@ -123,7 +121,7 @@ class IDETypeStateAnalysisBase
123121
container_type getLocalAliasesAndAllocas(d_t V, llvm::StringRef Fname);
124122

125123
/**
126-
* @brief Checks if the type machtes the type of interest.
124+
* @brief Checks if the type matches the type of interest.
127125
*/
128126
bool hasMatchingType(d_t V);
129127

@@ -132,7 +130,7 @@ class IDETypeStateAnalysisBase
132130
return generateFlow(FactToGenerate, LLVMZeroValue::getInstance());
133131
}
134132

135-
bool hasMatchingTypeName(const llvm::Type *Ty);
133+
bool hasMatchingTypeName(const llvm::DIType *DITy);
136134

137135
std::map<const llvm::Value *, LLVMAliasInfo::AliasSetTy> AliasCache;
138136
LLVMAliasInfoRef PT{};
@@ -283,11 +281,7 @@ class IDETypeStateAnalysis
283281
template <typename LL = l_t,
284282
typename = std::enable_if_t<HasJoinLatticeTraits<LL>>>
285283
TSConstant(l_t Value, EmptyType /*unused*/ = {}) noexcept
286-
: ConstantEdgeFunction<l_t>{Value} {
287-
if constexpr (!HasJoinLatticeTraits<l_t>) {
288-
this->TSD = TSD;
289-
}
290-
}
284+
: ConstantEdgeFunction<l_t>{Value} {}
291285

292286
/// XXX: Cannot default compose() and join(), because l_t does not implement
293287
/// JoinLatticeTraits (because bottom value is not constant)

include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/CSTDFILEIOTypeStateDescription.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
#include "llvm/Support/raw_ostream.h"
1717

18-
#include <map>
1918
#include <set>
2019
#include <string>
2120

include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFDescription.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h"
1414

15-
#include <map>
1615
#include <set>
1716
#include <string>
1817

include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212

1313
#include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h"
1414

15-
#include "llvm/IR/InstrTypes.h"
16-
1715
#include <set>
1816
#include <string>
1917

18+
namespace llvm {
19+
class CallBase;
20+
} // namespace llvm
21+
2022
namespace psr {
2123

2224
struct TypeStateDescriptionBase {

include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
#include "llvm/IR/PassManager.h"
2121

2222
#include <set>
23+
#include <vector>
2324

2425
namespace llvm {
2526
class Type;
2627
class Value;
2728
class Instruction;
2829
class AnalysisUsage;
2930
class Module;
31+
class DICompositeType;
3032
} // namespace llvm
3133

3234
namespace psr {
@@ -67,7 +69,7 @@ struct GeneralStatistics {
6769
size_t NumInstWithMultipleUses = 0;
6870
size_t NumInstsUsedOutsideBB = 0;
6971
size_t NonVoidInsts = 0;
70-
std::set<const llvm::Type *> AllocatedTypes;
72+
std::vector<const llvm::DICompositeType *> AllocatedTypes;
7173
std::set<const llvm::Instruction *> AllocaInstructions;
7274
std::set<const llvm::Instruction *> RetResInstructions;
7375
std::string ModuleName{};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/******************************************************************************
2+
* Copyright (c) 2025 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_UTILS_ALLOCATEDTYPES_H
11+
#define PHASAR_PHASARLLVM_UTILS_ALLOCATEDTYPES_H
12+
13+
#include "llvm/IR/DebugInfoMetadata.h"
14+
#include "llvm/IR/Module.h"
15+
16+
#include <vector>
17+
18+
namespace psr {
19+
[[nodiscard]] std::vector<const llvm::DICompositeType *>
20+
collectAllocatedTypes(const llvm::Module &Mod);
21+
} // namespace psr
22+
23+
#endif // PHASAR_PHASARLLVM_UTILS_ALLOCATEDTYPES_H

include/phasar/PhasarLLVM/Utils/LLVMShorthands.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ std::string llvmIRToShortString(const llvm::Value *V);
104104
[[nodiscard]] std::string llvmTypeToString(const llvm::Type *Ty,
105105
bool Shorten = false);
106106

107+
/**
108+
* @brief Returns a string-representation of a LLVM Debug-Info type.
109+
*
110+
* @param Shorten Tries to shorten the output
111+
*/
112+
[[nodiscard]] std::string llvmTypeToString(const llvm::DIType *Ty,
113+
bool Shorten = false);
114+
107115
LLVM_DUMP_METHOD void dumpIRValue(const llvm::Value *V);
108116
LLVM_DUMP_METHOD void dumpIRValue(const llvm::Instruction *V);
109117
LLVM_DUMP_METHOD void dumpIRValue(const llvm::Function *V);
@@ -283,6 +291,8 @@ class ModulesToSlotTracker {
283291
getVaListTagOrNull(const llvm::Function &Fun);
284292

285293
[[nodiscard]] bool isVaListAlloca(const llvm::AllocaInst &Alloc);
294+
295+
[[nodiscard]] const llvm::DIType *stripPointerTypes(const llvm::DIType *DITy);
286296
} // namespace psr
287297

288298
#endif

lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,12 @@
1818

1919
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
2020
#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h"
21-
#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h"
21+
#include "phasar/PhasarLLVM/Utils/AllocatedTypes.h"
2222
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
2323
#include "phasar/Utils/Logger.h"
2424

25-
#include "llvm/BinaryFormat/Dwarf.h"
26-
#include "llvm/IR/DebugInfoMetadata.h"
27-
#include "llvm/IR/DerivedTypes.h"
2825
#include "llvm/IR/Function.h"
2926
#include "llvm/IR/InstrTypes.h"
30-
#include "llvm/IR/Instructions.h"
31-
#include "llvm/Support/Casting.h"
3227
#include "llvm/Support/raw_ostream.h"
3328

3429
using namespace psr;
@@ -85,52 +80,10 @@ void RTAResolver::resolveVirtualCall(FunctionSetTy &PossibleTargets,
8580

8681
std::string RTAResolver::str() const { return "RTA"; }
8782

88-
static const llvm::DICompositeType *
89-
isCompositeStructType(const llvm::DIType *Ty) {
90-
if (const auto *CompTy = llvm::dyn_cast_if_present<llvm::DICompositeType>(Ty);
91-
CompTy && (CompTy->getTag() == llvm::dwarf::DW_TAG_structure_type ||
92-
CompTy->getTag() == llvm::dwarf::DW_TAG_class_type)) {
93-
94-
return CompTy;
95-
}
96-
97-
return nullptr;
98-
}
99-
10083
void RTAResolver::resolveAllocatedCompositeTypes() {
10184
if (!AllocatedCompositeTypes.empty()) {
10285
return;
10386
}
10487

105-
llvm::DenseSet<const llvm::DICompositeType *> AllocatedTypes;
106-
107-
for (const auto *Inst : IRDB->getAllInstructions()) {
108-
if (const auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(Inst)) {
109-
if (const auto *Ty = isCompositeStructType(getVarTypeFromIR(Alloca))) {
110-
AllocatedTypes.insert(Ty);
111-
}
112-
} else if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst)) {
113-
if (const auto *Callee = llvm::dyn_cast<llvm::Function>(
114-
Call->getCalledOperand()->stripPointerCastsAndAliases())) {
115-
if (psr::isHeapAllocatingFunction(Callee)) {
116-
const auto *MDNode = Call->getMetadata("heapallocsite");
117-
if (const auto *CompTy = llvm::
118-
#if LLVM_VERSION_MAJOR >= 15
119-
dyn_cast_if_present
120-
#else
121-
dyn_cast_or_null
122-
#endif
123-
<llvm::DICompositeType>(MDNode);
124-
isCompositeStructType(CompTy)) {
125-
126-
AllocatedTypes.insert(CompTy);
127-
}
128-
}
129-
}
130-
}
131-
}
132-
133-
AllocatedCompositeTypes.reserve(AllocatedTypes.size());
134-
AllocatedCompositeTypes.insert(AllocatedCompositeTypes.end(),
135-
AllocatedTypes.begin(), AllocatedTypes.end());
88+
AllocatedCompositeTypes = collectAllocatedTypes(*IRDB->getModule());
13689
}

lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,6 @@ psr::getVFTIndexAndVT(const llvm::CallBase *CallSite) {
8787
return std::nullopt;
8888
}
8989

90-
static const llvm::DIType *stripPointerTypes(const llvm::DIType *DITy) {
91-
while (const auto *DerivedTy =
92-
llvm::dyn_cast_if_present<llvm::DIDerivedType>(DITy)) {
93-
// get rid of the pointer
94-
DITy = DerivedTy->getBaseType();
95-
}
96-
return DITy;
97-
}
98-
9990
const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) {
10091
if (!CallSite || CallSite->arg_empty() ||
10192
(CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) {

lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.cpp

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99

1010
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h"
1111

12-
#include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h"
13-
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
1412
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
15-
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
1613
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h"
1714
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h"
1815
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h"
@@ -21,17 +18,17 @@
2118
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
2219
#include "phasar/Utils/Logger.h"
2320

24-
#include "llvm/ADT/DenseMap.h"
2521
#include "llvm/Demangle/Demangle.h"
26-
#include "llvm/IR/AbstractCallSite.h"
22+
#include "llvm/IR/DebugInfoMetadata.h"
2723
#include "llvm/IR/Function.h"
2824
#include "llvm/IR/Instruction.h"
25+
#include "llvm/IR/Instructions.h"
26+
#include "llvm/IR/Metadata.h"
2927
#include "llvm/IR/Value.h"
3028
#include "llvm/Support/Casting.h"
3129
#include "llvm/Support/ErrorHandling.h"
3230
#include "llvm/Support/raw_ostream.h"
3331

34-
#include <algorithm>
3532
#include <utility>
3633

3734
namespace psr::detail {
@@ -284,59 +281,23 @@ auto IDETypeStateAnalysisBase::getLocalAliasesAndAllocas(
284281
return AliasAndAllocas;
285282
}
286283

287-
bool IDETypeStateAnalysisBase::hasMatchingTypeName(const llvm::Type *Ty) {
288-
if (const auto *StructTy = llvm::dyn_cast<llvm::StructType>(Ty);
289-
StructTy && StructTy->hasName()) {
290-
return isTypeNameOfInterest(StructTy->getName());
284+
bool IDETypeStateAnalysisBase::hasMatchingTypeName(const llvm::DIType *DITy) {
285+
if (llvm::isa<llvm::DICompositeType>(DITy) && !DITy->getName().empty()) {
286+
return isTypeNameOfInterest(DITy->getName());
291287
}
292-
// primitive type
293-
std::string Str;
294-
llvm::raw_string_ostream S(Str);
295-
S << *Ty;
296-
S.flush();
297-
return isTypeNameOfInterest(Str);
288+
289+
return true; // Conservatively return true
298290
}
299291

300292
bool IDETypeStateAnalysisBase::hasMatchingType(d_t V) {
301-
// General case
302-
if (V->getType()->isPointerTy() && !V->getType()->isOpaquePointerTy()) {
303-
if (hasMatchingTypeName(V->getType()->getNonOpaquePointerElementType())) {
304-
return true;
305-
}
306-
// fallthrough
307-
}
308-
if (const auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(V)) {
309-
if (Alloca->getAllocatedType()->isPointerTy()) {
310-
if (Alloca->getAllocatedType()->isOpaquePointerTy() ||
311-
hasMatchingTypeName(
312-
Alloca->getAllocatedType()->getNonOpaquePointerElementType())) {
313-
return true;
314-
}
315-
}
316-
return false;
317-
}
318-
if (const auto *Load = llvm::dyn_cast<llvm::LoadInst>(V)) {
319-
if (Load->getType()->isPointerTy()) {
320-
if (Load->getType()->isOpaquePointerTy() ||
321-
hasMatchingTypeName(
322-
Load->getType()->getNonOpaquePointerElementType())) {
323-
return true;
324-
}
293+
if (const auto *VarTy = getVarTypeFromIR(V)) {
294+
if (const auto *BaseTy = stripPointerTypes(VarTy)) {
295+
return hasMatchingTypeName(BaseTy);
325296
}
326-
return false;
327-
}
328-
if (const auto *Store = llvm::dyn_cast<llvm::StoreInst>(V)) {
329-
if (Store->getValueOperand()->getType()->isPointerTy()) {
330-
if (Store->getValueOperand()->getType()->isOpaquePointerTy() ||
331-
hasMatchingTypeName(Store->getValueOperand()
332-
->getType()
333-
->getNonOpaquePointerElementType())) {
334-
return true;
335-
}
336-
}
337-
return false;
297+
298+
return isTypeNameOfInterest(VarTy->getName());
338299
}
339-
return false;
340-
}
341300

301+
return true;
302+
}
342303
} // namespace psr::detail

0 commit comments

Comments
 (0)