Repository: mchalupa/dg Branch: master Commit: dc3615d03fed Files: 506 Total size: 2.4 MB Directory structure: gitextract_sogryq7m/ ├── .clang-format ├── .clang-tidy ├── .git-blame-ignore-revs ├── .github/ │ └── workflows/ │ ├── clang-format.yml │ ├── docker.yml │ ├── hash_map.yml │ ├── linux.yml │ ├── mac.yml │ └── svf.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Changelog ├── Dockerfile ├── LICENSE ├── README.md ├── dg.spec.rpkg ├── doc/ │ ├── CDA.md │ ├── DDA.md │ ├── PTA.md │ ├── README.md │ ├── SVF.md │ ├── compiling.md │ ├── compiling_ubuntu_trusty.md │ ├── compiling_ubuntu_xenial.md │ ├── downloading.md │ ├── llvm-slicer.md │ └── tools.md ├── include/ │ └── dg/ │ ├── ADT/ │ │ ├── Bits.h │ │ ├── Bitvector.h │ │ ├── DGContainer.h │ │ ├── DisjunctiveIntervalMap.h │ │ ├── HashMap.h │ │ ├── HashMapImpl.h │ │ ├── IntervalsList.h │ │ ├── Map.h │ │ ├── NumberSet.h │ │ ├── Queue.h │ │ ├── STLHashMap.h │ │ ├── SetQueue.h │ │ └── TslHopscotchHashMap.h │ ├── AnalysisOptions.h │ ├── BBlock.h │ ├── BBlockBase.h │ ├── BBlocksBuilder.h │ ├── BFS.h │ ├── CallGraph/ │ │ └── CallGraph.h │ ├── ControlDependence/ │ │ └── ControlDependenceAnalysisOptions.h │ ├── DFS.h │ ├── DG2Dot.h │ ├── DGParameters.h │ ├── DataDependence/ │ │ ├── DataDependence.h │ │ ├── DataDependenceAnalysisImpl.h │ │ └── DataDependenceAnalysisOptions.h │ ├── DependenceGraph.h │ ├── Dominators/ │ │ ├── DominanceFrontiers.h │ │ └── PostDominanceFrontiers.h │ ├── MemorySSA/ │ │ ├── Definitions.h │ │ ├── DefinitionsMap.h │ │ ├── MemorySSA.h │ │ └── ModRef.h │ ├── MemoryState.h │ ├── Node.h │ ├── NodesWalk.h │ ├── Offset.h │ ├── PointerAnalysis/ │ │ ├── MemoryObject.h │ │ ├── PSNode.h │ │ ├── Pointer.h │ │ ├── PointerAnalysis.h │ │ ├── PointerAnalysisFI.h │ │ ├── PointerAnalysisFS.h │ │ ├── PointerAnalysisFSInv.h │ │ ├── PointerAnalysisOptions.h │ │ ├── PointerGraph.h │ │ ├── PointerGraphOptimizations.h │ │ ├── PointerGraphValidator.h │ │ ├── PointsToMapping.h │ │ ├── PointsToSet.h │ │ └── PointsToSets/ │ │ ├── AlignedPointerIdPointsToSet.h │ │ ├── AlignedSmallOffsetsPointsToSet.h │ │ ├── LookupTable.h │ │ ├── OffsetsSetPointsToSet.h │ │ ├── PointerIdPointsToSet.h │ │ ├── SeparateOffsetsPointsToSet.h │ │ ├── SimplePointsToSet.h │ │ └── SmallOffsetsPointsToSet.h │ ├── ReadWriteGraph/ │ │ ├── DefSite.h │ │ ├── RWBBlock.h │ │ ├── RWNode.h │ │ ├── RWSubgraph.h │ │ └── ReadWriteGraph.h │ ├── SCC.h │ ├── Slicing.h │ ├── SubgraphBase.h │ ├── SubgraphNode.h │ ├── SystemDependenceGraph/ │ │ ├── DGArgumentPair.h │ │ ├── DGBBlock.h │ │ ├── DGElement.h │ │ ├── DGNode.h │ │ ├── DGNodeCall.h │ │ ├── DGParameters.h │ │ ├── DepDGElement.h │ │ ├── DependenceGraph.h │ │ └── SystemDependenceGraph.h │ ├── ValueRelations/ │ │ ├── Bucket.h │ │ ├── Relations.h │ │ └── RelationsGraph.h │ ├── legacy/ │ │ ├── Analysis.h │ │ ├── BFS.h │ │ ├── DFS.h │ │ ├── DataFlowAnalysis.h │ │ └── NodesWalk.h │ ├── llvm/ │ │ ├── CallGraph/ │ │ │ └── CallGraph.h │ │ ├── ControlDependence/ │ │ │ ├── ControlDependence.h │ │ │ ├── LLVMControlDependenceAnalysisImpl.h │ │ │ └── LLVMControlDependenceAnalysisOptions.h │ │ ├── DataDependence/ │ │ │ ├── DataDependence.h │ │ │ └── LLVMDataDependenceAnalysisOptions.h │ │ ├── Dominators/ │ │ │ └── Dominators.h │ │ ├── LLVMAnalysisOptions.h │ │ ├── LLVMDG2Dot.h │ │ ├── LLVMDGAssemblyAnnotationWriter.h │ │ ├── LLVMDependenceGraph.h │ │ ├── LLVMDependenceGraphBuilder.h │ │ ├── LLVMNode.h │ │ ├── LLVMSlicer.h │ │ ├── PointerAnalysis/ │ │ │ ├── DGPointerAnalysis.h │ │ │ ├── LLVMPointerAnalysisOptions.h │ │ │ ├── LLVMPointsToSet.h │ │ │ ├── PointerAnalysis.h │ │ │ ├── PointerGraph.h │ │ │ └── SVFPointerAnalysis.h │ │ ├── SystemDependenceGraph/ │ │ │ ├── SDG2Dot.h │ │ │ ├── SystemDependenceGraph.h │ │ │ └── SystemDependenceGraphBuilder.h │ │ ├── ThreadRegions/ │ │ │ ├── ControlFlowGraph.h │ │ │ ├── MayHappenInParallel.h │ │ │ └── ThreadRegion.h │ │ └── ValueRelations/ │ │ ├── GraphBuilder.h │ │ ├── GraphElements.h │ │ ├── RelationsAnalyzer.h │ │ ├── StructureAnalyzer.h │ │ ├── StructureElements.h │ │ ├── UniquePtrVector.h │ │ ├── ValueRelations.h │ │ └── getValName.h │ └── util/ │ ├── TimeMeasure.h │ ├── cow_shared_ptr.h │ ├── debug.h │ └── iterators.h ├── lib/ │ ├── BBlockBase.cpp │ ├── CMakeLists.txt │ ├── ControlDependence/ │ │ ├── CDGraph.h │ │ ├── ControlClosure.h │ │ ├── DOD.h │ │ ├── DODNTSCD.h │ │ ├── NTSCD.cpp │ │ └── NTSCD.h │ ├── Debug.cpp │ ├── MemorySSA/ │ │ ├── Definitions.cpp │ │ ├── MemorySSA.cpp │ │ └── ModRef.cpp │ ├── Offset.cpp │ ├── PointerAnalysis/ │ │ ├── Pointer.cpp │ │ ├── PointerAnalysis.cpp │ │ ├── PointerGraph.cpp │ │ ├── PointerGraphOptimizations.cpp │ │ ├── PointerGraphValidator.cpp │ │ └── PointsToSet.cpp │ ├── ReadWriteGraph/ │ │ └── ReadWriteGraph.cpp │ ├── SystemDependenceGraph/ │ │ └── DependenceGraph.cpp │ ├── ValueRelations/ │ │ └── Relations.cpp │ └── llvm/ │ ├── ControlDependence/ │ │ ├── ControlClosure.h │ │ ├── ControlDependence.cpp │ │ ├── DOD.h │ │ ├── GraphBuilder.h │ │ ├── IGraphBuilder.h │ │ ├── InterproceduralCD.cpp │ │ ├── InterproceduralCD.h │ │ ├── NTSCD.h │ │ ├── SCD.cpp │ │ ├── SCD.h │ │ └── legacy/ │ │ ├── Block.cpp │ │ ├── Block.h │ │ ├── Function.cpp │ │ ├── Function.h │ │ ├── GraphBuilder.cpp │ │ ├── GraphBuilder.h │ │ ├── NTSCD.cpp │ │ ├── NTSCD.h │ │ └── TarjanAnalysis.h │ ├── DataDependenceAnalysis/ │ │ └── LLVMDataDependenceAnalysis.cpp │ ├── DefUse/ │ │ ├── DefUse.cpp │ │ └── DefUse.h │ ├── Dominators/ │ │ └── PostDominators.cpp │ ├── ForkJoin/ │ │ ├── ForkJoin.cpp │ │ └── ForkJoin.h │ ├── GraphBuilder.h │ ├── LLVMDGVerifier.cpp │ ├── LLVMDGVerifier.h │ ├── LLVMDependenceGraph.cpp │ ├── LLVMNode.cpp │ ├── PointerAnalysis/ │ │ ├── Block.cpp │ │ ├── Calls.cpp │ │ ├── Constants.cpp │ │ ├── Globals.cpp │ │ ├── Instructions.cpp │ │ ├── Interprocedural.cpp │ │ ├── PointerAnalysis.cpp │ │ ├── PointerGraph.cpp │ │ ├── PointerGraphValidator.cpp │ │ ├── PointerGraphValidator.h │ │ ├── Structure.cpp │ │ └── Threads.cpp │ ├── ReadWriteGraph/ │ │ ├── Calls.cpp │ │ ├── Instructions.cpp │ │ ├── LLVMReadWriteGraphBuilder.cpp │ │ └── LLVMReadWriteGraphBuilder.h │ ├── SummaryEdges.cpp │ ├── SystemDependenceGraph/ │ │ ├── Dependencies.cpp │ │ ├── SDG2Dot.cpp │ │ └── SystemDependenceGraph.cpp │ ├── ThreadRegions/ │ │ ├── Graphs/ │ │ │ ├── BlockGraph.cpp │ │ │ ├── BlockGraph.h │ │ │ ├── ControlFlowGraph.cpp │ │ │ ├── CriticalSectionsBuilder.cpp │ │ │ ├── CriticalSectionsBuilder.h │ │ │ ├── FunctionGraph.cpp │ │ │ ├── FunctionGraph.h │ │ │ ├── GraphBuilder.cpp │ │ │ ├── GraphBuilder.h │ │ │ ├── ThreadRegionsBuilder.cpp │ │ │ └── ThreadRegionsBuilder.h │ │ ├── MayHappenInParallel.cpp │ │ ├── Nodes/ │ │ │ ├── CallFuncPtrNode.cpp │ │ │ ├── CallFuncPtrNode.h │ │ │ ├── CallNode.cpp │ │ │ ├── CallNode.h │ │ │ ├── CallReturnNode.cpp │ │ │ ├── CallReturnNode.h │ │ │ ├── EntryNode.cpp │ │ │ ├── EntryNode.h │ │ │ ├── ExitNode.cpp │ │ │ ├── ExitNode.h │ │ │ ├── ForkNode.cpp │ │ │ ├── ForkNode.h │ │ │ ├── GeneralNode.cpp │ │ │ ├── GeneralNode.h │ │ │ ├── JoinNode.cpp │ │ │ ├── JoinNode.h │ │ │ ├── LockNode.cpp │ │ │ ├── LockNode.h │ │ │ ├── Node.cpp │ │ │ ├── Node.h │ │ │ ├── NodeIterator.cpp │ │ │ ├── NodeIterator.h │ │ │ ├── Nodes.h │ │ │ ├── ReturnNode.cpp │ │ │ ├── ReturnNode.h │ │ │ ├── UnlockNode.cpp │ │ │ └── UnlockNode.h │ │ └── ThreadRegion.cpp │ ├── ValueRelations/ │ │ ├── GraphBuilder.cpp │ │ ├── GraphElements.cpp │ │ ├── RelationsAnalyzer.cpp │ │ ├── StructureAnalyzer.cpp │ │ └── ValueRelations.cpp │ └── llvm-utils.h ├── misc/ │ └── benchexec/ │ ├── README.md │ ├── dgtool.py │ ├── llvm-slicer-tests.xml │ └── slicing-tests.set ├── tests/ │ ├── CMakeLists.txt │ ├── adt-test.cpp │ ├── bitvector-test.cpp │ ├── catch-main.cpp │ ├── catch2/ │ │ └── catch.hpp │ ├── cmd-args.py │ ├── disjunctive-intervals-map-test.cpp │ ├── fuzzing/ │ │ ├── CMakeLists.txt │ │ ├── bitvector1.cpp │ │ ├── disjunctive-map1.cpp │ │ └── numbers-set1.cpp │ ├── llvm-dg-test.cpp │ ├── nodes-walk-test.cpp │ ├── numbers-set-test.cpp │ ├── points-to-set-test.cpp │ ├── points-to-test.cpp │ ├── ptset-benchmark.cpp │ ├── rdmap-test.cpp │ ├── readwritegraph-test.cpp │ ├── slicing/ │ │ ├── CMakeLists.txt │ │ ├── sources/ │ │ │ ├── a_ptr.c │ │ │ ├── alias_of_return.c │ │ │ ├── atomic1.c │ │ │ ├── atomic2.c │ │ │ ├── atomic3.c │ │ │ ├── bitcast1.c │ │ │ ├── bitcast2.c │ │ │ ├── bitcast3.c │ │ │ ├── bitcast4.c │ │ │ ├── bitcast5.c │ │ │ ├── bitcast6.c │ │ │ ├── control-regression1.c │ │ │ ├── cyclic-realloc.c │ │ │ ├── dynalloc1.c │ │ │ ├── dynalloc2.c │ │ │ ├── dynalloc3.c │ │ │ ├── dynalloc4.c │ │ │ ├── dynalloc5.c │ │ │ ├── dynalloc6.c │ │ │ ├── dynalloc7.c │ │ │ ├── foo.c │ │ │ ├── fptoui1.c │ │ │ ├── funcarray1.c │ │ │ ├── funcarray2.c │ │ │ ├── funcarray3.c │ │ │ ├── funcptr-regression1.c │ │ │ ├── funcptr1.c │ │ │ ├── funcptr10.c │ │ │ ├── funcptr11.c │ │ │ ├── funcptr12.c │ │ │ ├── funcptr13.c │ │ │ ├── funcptr14.c │ │ │ ├── funcptr15.c │ │ │ ├── funcptr16.c │ │ │ ├── funcptr2.c │ │ │ ├── funcptr3.c │ │ │ ├── funcptr4.c │ │ │ ├── funcptr5.c │ │ │ ├── funcptr6.c │ │ │ ├── funcptr7.c │ │ │ ├── funcptr8.c │ │ │ ├── funcptr9.c │ │ │ ├── get_int.c │ │ │ ├── get_output.c │ │ │ ├── get_ptr.c │ │ │ ├── glob_ptr-a.c │ │ │ ├── glob_ptr.c │ │ │ ├── global-init.c │ │ │ ├── global1.c │ │ │ ├── global10.c │ │ │ ├── global2.c │ │ │ ├── global3.c │ │ │ ├── global4.c │ │ │ ├── global5.c │ │ │ ├── global6.c │ │ │ ├── global7.c │ │ │ ├── global8.c │ │ │ ├── global9.c │ │ │ ├── globalptr1.c │ │ │ ├── globalptr2.c │ │ │ ├── globalptr3.c │ │ │ ├── globalptr4.c │ │ │ ├── interprocedural1.c │ │ │ ├── interprocedural2.c │ │ │ ├── interprocedural3.c │ │ │ ├── interprocedural4.c │ │ │ ├── interprocedural5.c │ │ │ ├── interprocedural6.c │ │ │ ├── interprocedural7.c │ │ │ ├── interprocedural8-a.c │ │ │ ├── interprocedural8.c │ │ │ ├── interprocedural8.output │ │ │ ├── interprocedural9.c │ │ │ ├── list1.c │ │ │ ├── list2.c │ │ │ ├── list3.c │ │ │ ├── list4.c │ │ │ ├── list5.c │ │ │ ├── list6.c │ │ │ ├── list7.c │ │ │ ├── list8.c │ │ │ ├── llvmmemcpy.c │ │ │ ├── llvmmemcpy2.c │ │ │ ├── loop1.c │ │ │ ├── loop2.c │ │ │ ├── loop3.c │ │ │ ├── loop4.c │ │ │ ├── loop5.c │ │ │ ├── malloc-redef.c │ │ │ ├── memcpy1.c │ │ │ ├── memcpy2.c │ │ │ ├── memcpy3.c │ │ │ ├── memcpy4.c │ │ │ ├── memcpy5.c │ │ │ ├── memcpy6.c │ │ │ ├── memset1.c │ │ │ ├── negoffset1.c │ │ │ ├── negoffset2.c │ │ │ ├── negoffset3.c │ │ │ ├── phi1.c │ │ │ ├── phi2.c │ │ │ ├── phi3.c │ │ │ ├── phi4.c │ │ │ ├── pointers1.c │ │ │ ├── pointers2.c │ │ │ ├── pointers3.c │ │ │ ├── pointers4.c │ │ │ ├── pointers5.c │ │ │ ├── pointers6.c │ │ │ ├── pointers7.c │ │ │ ├── pta-inv-infinite-loop.c │ │ │ ├── pta_fs_regression1.c │ │ │ ├── pta_regression2.c │ │ │ ├── ptr-9.c │ │ │ ├── ptr.c │ │ │ ├── ptrarray1.c │ │ │ ├── ptrarray2.c │ │ │ ├── ptrtoint1.c │ │ │ ├── ptrtoint2.c │ │ │ ├── ptrtoint3.c │ │ │ ├── ptrtoint4.c │ │ │ ├── ptrtoint5.c │ │ │ ├── ptrtoint6.c │ │ │ ├── ptrtoint7.c │ │ │ ├── realloc1.c │ │ │ ├── realloc2.c │ │ │ ├── realloc3.c │ │ │ ├── recursive1.c │ │ │ ├── recursive2.c │ │ │ ├── recursive3.c │ │ │ ├── recursive4.c │ │ │ ├── recursive5.c │ │ │ ├── regression1.c │ │ │ ├── sum1.c │ │ │ ├── sum2.c │ │ │ ├── sum3.c │ │ │ ├── switch1.c │ │ │ ├── switch2.c │ │ │ ├── test1.c │ │ │ ├── test2.c │ │ │ ├── test22.c │ │ │ ├── test222.c │ │ │ ├── test3.c │ │ │ ├── test4.c │ │ │ ├── test5.c │ │ │ ├── test6.c │ │ │ ├── test7.c │ │ │ ├── test8.c │ │ │ ├── threads1.c │ │ │ ├── undefcall1_true-unreach-call.c │ │ │ ├── undefcall2_true-unreach-call.c │ │ │ ├── unknown-interproc.c │ │ │ ├── unknown-interproc2-a.c │ │ │ ├── unknown-interproc2.c │ │ │ ├── unknown-interproc3.c │ │ │ ├── unknownptr1.c │ │ │ ├── unknownptr10-a.c │ │ │ ├── unknownptr10.c │ │ │ ├── unknownptr11.c │ │ │ ├── unknownptr2.c │ │ │ ├── unknownptr3.c │ │ │ ├── unknownptr4.c │ │ │ ├── unknownptr5.c │ │ │ ├── unknownptr6.c │ │ │ ├── unknownptr7.c │ │ │ ├── unknownptr8.c │ │ │ ├── unknownptr9.c │ │ │ ├── unknownptrfoo.c │ │ │ ├── unknownptrfoo2.c │ │ │ ├── vararg1.c │ │ │ ├── vararg2.c │ │ │ ├── vararg3.c │ │ │ ├── vararg4.c │ │ │ └── wl_list.c │ │ ├── test-runner.py │ │ ├── test_assert.c │ │ ├── test_assert.h │ │ └── tests.py │ ├── slicing-stress.sh │ ├── thread-regions-test-files/ │ │ ├── pthread_exit.c │ │ └── simple.c │ ├── thread-regions-test.cpp │ └── value-relations-test.cpp └── tools/ ├── CMakeLists.txt ├── dgtool ├── git-version.h.in ├── include/ │ └── dg/ │ └── tools/ │ ├── llvm-slicer-opts.h │ ├── llvm-slicer-preprocess.h │ ├── llvm-slicer-utils.h │ └── llvm-slicer.h ├── llvm-cda-bench.cpp ├── llvm-cda-dump.cpp ├── llvm-cda-stress.cpp ├── llvm-cg-dump.cpp ├── llvm-dda-dump.cpp ├── llvm-dg-dump.cpp ├── llvm-ntscd-dump.cpp ├── llvm-pta-ben.cpp ├── llvm-pta-compare.cpp ├── llvm-pta-dump.cpp ├── llvm-sdg-dump.cpp ├── llvm-slicer-crit.cpp ├── llvm-slicer-metadata.cpp ├── llvm-slicer-opts.cpp ├── llvm-slicer-preprocess.cpp ├── llvm-slicer-utils.cpp ├── llvm-slicer.cpp ├── llvm-thread-regions-dump.cpp ├── llvm-to-source.cpp ├── llvm-vr-dump.cpp ├── llvmdda-dump ├── llvmdg-show ├── pta-show └── sliced-diff.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .clang-format ================================================ --- Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -2 AlignAfterOpenBracket: Align AlignConsecutiveMacros: false AlignConsecutiveAssignments: false AlignConsecutiveBitFields: false AlignConsecutiveDeclarations: false AlignEscapedNewlines: Right AlignOperands: Align AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllConstructorInitializersOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortEnumsOnASingleLine: true AllowShortBlocksOnASingleLine: Empty AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BinPackParameters: true BraceWrapping: AfterCaseLabel: false AfterClass: false AfterControlStatement: Never AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false AfterExternBlock: false BeforeCatch: false BeforeElse: false BeforeLambdaBody: false BeforeWhile: false IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeInheritanceComma: false BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 80 CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 8 ContinuationIndentWidth: 8 Cpp11BracedListStyle: true DeriveLineEnding: false DerivePointerAlignment: false DisableFormat: false FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH IncludeBlocks: Preserve IndentCaseLabels: false IndentCaseBlocks: false IndentGotoLabels: false IndentPPDirectives: None IndentExternBlock: AfterExternBlock IndentWidth: 4 IndentWrappedFunctionNames: false InsertTrailingCommas: None JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 2 ObjCBreakBeforeNestedBlockParam: true ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakAssignment: 2 PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: true SortIncludes: true SortUsingDeclarations: true SpaceAfterCStyleCast: true SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatements SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false Standard: Latest TabWidth: 8 UseCRLF: false UseTab: Never ... ================================================ FILE: .clang-tidy ================================================ --- # vim: syntax=yaml # we might want to enable llvm-namespace-comment in the future Checks: 'clang-diagnostic-*,clang-analyzer-*,modernize-*,-modernize-use-auto,-modernize-use-trailing-return-type,bugprone-*,llvm-*,-llvm-header-guard,-llvm-namespace-comment,misc-misplaced-const,misc-non-copyable-objects,misc-redundant-expression,misc-static-assert,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,performace-*,readability-*,-readability-isolate-declaration,-readability-braces-around-statements,-readability-implicit-bool-conversion,-readability-static-accessed-through-instance,-readability-identifier-length' WarningsAsErrors: '' HeaderFilterRegex: 'include/|lib/|tools/' AnalyzeTemporaryDtors: false FormatStyle: file CheckOptions: - key: bugprone-argument-comment.CommentBoolLiterals value: '0' - key: bugprone-argument-comment.CommentCharacterLiterals value: '0' - key: bugprone-argument-comment.CommentFloatLiterals value: '0' - key: bugprone-argument-comment.CommentIntegerLiterals value: '0' - key: bugprone-argument-comment.CommentNullPtrs value: '0' - key: bugprone-argument-comment.CommentStringLiterals value: '0' - key: bugprone-argument-comment.CommentUserDefinedLiterals value: '0' - key: bugprone-argument-comment.IgnoreSingleArgument value: '0' - key: bugprone-argument-comment.StrictMode value: '0' - key: bugprone-assert-side-effect.AssertMacros value: assert - key: bugprone-assert-side-effect.CheckFunctionCalls value: 'false' - key: bugprone-dangling-handle.HandleClasses value: 'std::basic_string_view;std::experimental::basic_string_view' - key: bugprone-dynamic-static-initializers.HeaderFileExtensions value: ';h;hh;hpp;hxx' - key: bugprone-exception-escape.FunctionsThatShouldNotThrow value: '' - key: bugprone-exception-escape.IgnoredExceptions value: '' - key: bugprone-misplaced-widening-cast.CheckImplicitCasts value: 'false' - key: bugprone-narrowing-conversions.PedanticMode value: 'false' - key: bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion value: 'true' - key: bugprone-not-null-terminated-result.WantToUseSafeFunctions value: 'true' - key: bugprone-reserved-identifier.AggressiveDependentMemberLookup value: 'false' - key: bugprone-reserved-identifier.AllowedIdentifiers value: '' - key: bugprone-reserved-identifier.Invert value: 'false' - key: bugprone-signed-char-misuse.CharTypdefsToIgnore value: '' - key: bugprone-signed-char-misuse.DiagnoseSignedUnsignedCharComparisons value: 'true' - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant value: 'true' - key: bugprone-sizeof-expression.WarnOnSizeOfConstant value: 'true' - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression value: 'false' - key: bugprone-sizeof-expression.WarnOnSizeOfThis value: 'true' - key: bugprone-string-constructor.LargeLengthThreshold value: '8388608' - key: bugprone-string-constructor.WarnOnLargeLength value: 'true' - key: bugprone-suspicious-enum-usage.StrictMode value: 'false' - key: bugprone-suspicious-include.HeaderFileExtensions value: ';h;hh;hpp;hxx' - key: bugprone-suspicious-include.ImplementationFileExtensions value: 'c;cc;cpp;cxx' - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens value: '5' - key: bugprone-suspicious-missing-comma.RatioThreshold value: '0.200000' - key: bugprone-suspicious-missing-comma.SizeThreshold value: '5' - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions value: '' - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison value: 'true' - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison value: 'false' - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit value: '16' - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField value: 'true' - key: bugprone-unused-return-value.CheckedFunctions value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty;::std::back_inserter;::std::distance;::std::find;::std::find_if;::std::inserter;::std::lower_bound;::std::make_pair;::std::map::count;::std::map::find;::std::map::lower_bound;::std::multimap::equal_range;::std::multimap::upper_bound;::std::set::count;::std::set::find;::std::setfill;::std::setprecision;::std::setw;::std::upper_bound;::std::vector::at;::bsearch;::ferror;::feof;::isalnum;::isalpha;::isblank;::iscntrl;::isdigit;::isgraph;::islower;::isprint;::ispunct;::isspace;::isupper;::iswalnum;::iswprint;::iswspace;::isxdigit;::memchr;::memcmp;::strcmp;::strcoll;::strncmp;::strpbrk;::strrchr;::strspn;::strstr;::wcscmp;::access;::bind;::connect;::difftime;::dlsym;::fnmatch;::getaddrinfo;::getopt;::htonl;::htons;::iconv_open;::inet_addr;::isascii;::isatty;::mmap;::newlocale;::openat;::pathconf;::pthread_equal;::pthread_getspecific;::pthread_mutex_trylock;::readdir;::readlink;::recvmsg;::regexec;::scandir;::semget;::setjmp;::shm_open;::shmget;::sigismember;::strcasecmp;::strsignal;::ttyname' - key: cert-dcl16-c.NewSuffixes value: 'L;LL;LU;LLU' - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField value: '0' - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons value: '0' - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors value: '1' - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: '1' - key: google-readability-braces-around-statements.ShortStatementLines value: '1' - key: google-readability-function-size.StatementThreshold value: '800' - key: google-readability-namespace-comments.ShortNamespaceLines value: '10' - key: google-readability-namespace-comments.SpacesBeforeComments value: '2' - key: llvm-else-after-return.WarnOnConditionVariables value: 'false' - key: llvm-else-after-return.WarnOnUnfixable value: 'false' - key: llvm-header-guard.HeaderFileExtensions value: ';h;hh;hpp;hxx' - key: llvm-namespace-comment.ShortNamespaceLines value: '1' - key: llvm-namespace-comment.SpacesBeforeComments value: '1' - key: llvm-qualified-auto.AddConstToQualified value: 'false' - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: 'false' - key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables value: 'false' - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries value: 'true' - key: misc-throw-by-value-catch-by-reference.WarnOnLargeObjects value: 'false' - key: modernize-avoid-bind.PermissiveParameterList value: 'false' - key: modernize-loop-convert.MaxCopySize value: '16' - key: modernize-loop-convert.MinConfidence value: reasonable - key: modernize-loop-convert.NamingStyle value: CamelCase - key: modernize-make-shared.IgnoreMacros value: 'true' - key: modernize-make-shared.IncludeStyle value: llvm - key: modernize-make-shared.MakeSmartPtrFunction value: 'std::make_shared' - key: modernize-make-shared.MakeSmartPtrFunctionHeader value: memory - key: modernize-make-unique.IgnoreMacros value: 'true' - key: modernize-make-unique.IncludeStyle value: llvm - key: modernize-make-unique.MakeSmartPtrFunction value: 'std::make_unique' - key: modernize-make-unique.MakeSmartPtrFunctionHeader value: memory - key: modernize-pass-by-value.IncludeStyle value: llvm - key: modernize-pass-by-value.ValuesOnly value: 'false' - key: modernize-raw-string-literal.DelimiterStem value: lit - key: modernize-raw-string-literal.ReplaceShorterLiterals value: 'false' - key: modernize-replace-auto-ptr.IncludeStyle value: llvm - key: modernize-replace-disallow-copy-and-assign-macro.MacroName value: DISALLOW_COPY_AND_ASSIGN - key: modernize-replace-random-shuffle.IncludeStyle value: llvm - key: modernize-use-bool-literals.IgnoreMacros value: 'true' - key: modernize-use-default-member-init.IgnoreMacros value: 'true' - key: modernize-use-default-member-init.UseAssignment value: 'false' - key: modernize-use-emplace.ContainersWithPushBack value: '::std::vector;::std::list;::std::deque' - key: modernize-use-emplace.IgnoreImplicitConstructors value: 'false' - key: modernize-use-emplace.SmartPointers value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr' - key: modernize-use-emplace.TupleMakeFunctions value: '::std::make_pair;::std::make_tuple' - key: modernize-use-emplace.TupleTypes value: '::std::pair;::std::tuple' - key: modernize-use-equals-default.IgnoreMacros value: 'true' - key: modernize-use-equals-delete.IgnoreMacros value: 'true' - key: modernize-use-nodiscard.ReplacementString value: '[[nodiscard]]' - key: modernize-use-noexcept.ReplacementString value: '' - key: modernize-use-noexcept.UseNoexceptFalse value: 'true' - key: modernize-use-nullptr.NullMacros value: 'NULL' - key: modernize-use-override.AllowOverrideAndFinal value: 'false' - key: modernize-use-override.FinalSpelling value: final - key: modernize-use-override.IgnoreDestructors value: 'false' - key: modernize-use-override.OverrideSpelling value: override - key: modernize-use-transparent-functors.SafeMode value: 'false' - key: modernize-use-using.IgnoreMacros value: 'true' - key: readability-braces-around-statements.ShortStatementLines value: '0' - key: readability-else-after-return.WarnOnConditionVariables value: 'true' - key: readability-else-after-return.WarnOnUnfixable value: 'true' - key: readability-function-size.BranchThreshold value: '4294967295' - key: readability-function-size.LineThreshold value: '4294967295' - key: readability-function-size.NestingThreshold value: '4294967295' - key: readability-function-size.ParameterThreshold value: '4294967295' - key: readability-function-size.StatementThreshold value: '800' - key: readability-function-size.VariableThreshold value: '4294967295' - key: readability-identifier-naming.AggressiveDependentMemberLookup value: 'false' - key: readability-identifier-naming.IgnoreFailedSplit value: 'false' - key: readability-identifier-naming.IgnoreMainLikeFunctions value: 'false' - key: readability-implicit-bool-conversion.AllowIntegerConditions value: 'true' - key: readability-implicit-bool-conversion.AllowPointerConditions value: 'true' - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros value: 'true' - key: readability-inconsistent-declaration-parameter-name.Strict value: 'false' - key: readability-magic-numbers.IgnoreAllFloatingPointValues value: 'false' - key: readability-magic-numbers.IgnoreBitFieldsWidths value: 'true' - key: readability-magic-numbers.IgnorePowersOf2IntegerValues value: 'false' - key: readability-magic-numbers.IgnoredFloatingPointValues value: '1.0;100.0;' - key: readability-magic-numbers.IgnoredIntegerValues value: '1;2;3;4;' - key: readability-qualified-auto.AddConstToQualified value: 'true' - key: readability-redundant-declaration.IgnoreMacros value: 'true' - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors value: 'false' - key: readability-redundant-smartptr-get.IgnoreMacros value: 'true' - key: readability-redundant-string-init.StringNames value: '::std::basic_string' - key: readability-simplify-boolean-expr.ChainedConditionalAssignment value: 'false' - key: readability-simplify-boolean-expr.ChainedConditionalReturn value: 'false' - key: readability-simplify-subscript-expr.Types value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array' - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold value: '3' - key: readability-uppercase-literal-suffix.IgnoreMacros value: 'true' - key: readability-uppercase-literal-suffix.NewSuffixes value: '' ... ================================================ FILE: .git-blame-ignore-revs ================================================ # Reformat the whole project 2e60545c73a872b95d3c32a097e351ed9bfd8bf6 a69378f4f29a63d28cb79e0d6728d069353b19c8 ================================================ FILE: .github/workflows/clang-format.yml ================================================ --- name: Find unformatted files on: [push, pull_request] jobs: Format: name: Find unformatted files runs-on: ubuntu-22.04 steps: - name: Checkout DG uses: actions/checkout@v3 - name: Install clang-format 14 run: | sudo apt install clang-format-14 - name: Find unformatted files # Based on https://rigtorp.se/notes/clang-format/. run: | set -o pipefail find . -regextype posix-extended \ -iregex '\./(include|lib|tests|tools)/.*\.(h|c|cpp|hpp)' \ -o -iregex '\./tests/catch2' -prune -type f | \ xargs clang-format-14 --style=file --dry-run -Werror --color=true ================================================ FILE: .github/workflows/docker.yml ================================================ --- name: Docker Image on: [push, pull_request] jobs: Docker: runs-on: ubuntu-latest steps: - name: Checkout DG uses: actions/checkout@v3 - name: Build the Docker image run: | docker build . --file Dockerfile \ --build-arg GIT_REF=$GITHUB_REF \ --build-arg GIT_REPO=$GITHUB_REPOSITORY \ --tag dg:$(date +%s) ================================================ FILE: .github/workflows/hash_map.yml ================================================ --- name: DG + External Hash Maps on: [push, pull_request] jobs: Ubuntu: strategy: fail-fast: false matrix: os: [ubuntu-20.04] compiler: [gcc, clang] hashmap: [tsl-hopscotch] runs-on: ${{matrix.os}} env: # for colours in ninja CLICOLOR_FORCE: 1 steps: - name: Checkout DG uses: actions/checkout@v3 - name: Checkout TSL Hopscotch uses: actions/checkout@v3 with: repository: Tessil/hopscotch-map path: tsl-hopscotch - name: Install dependencies run: | sudo apt update sudo apt install ccache cmake ninja-build clang-10 llvm-10-dev - name: Set environment id: env run: | # set expected name of selected hashmap case "${{matrix.hashmap}}" in "tsl-hopscotch") echo "HASHMAP=TSL_HOPSCOTCH_DIR" >> $GITHUB_ENV;; *) echo "Unknown hashmap selected." && exit 1;; esac if [[ "${{matrix.compiler}}" = "clang" ]]; then echo "CC=clang-10" >> $GITHUB_ENV echo "CXX=clang++-10" >> $GITHUB_ENV # force coloured output echo "CFLAGS=$CFLAGS -fcolor-diagnostics" >> $GITHUB_ENV echo "CXXFLAGS=$CXXFLAGS -fcolor-diagnostics" >> $GITHUB_ENV else echo "CC=gcc" >> $GITHUB_ENV echo "CXX=g++" >> $GITHUB_ENV # force coloured output echo "CFLAGS=$CFLAGS -fdiagnostics-color=always" >> $GITHUB_ENV echo "CXXFLAGS=$CXXFLAGS -fdiagnostics-color=always" >> $GITHUB_ENV fi # set up ccache sudo /usr/sbin/update-ccache-symlinks echo "/usr/lib/ccache" >> $GITHUB_PATH echo "CCACHE_BASEDIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> $GITHUB_ENV echo "CCACHE_COMPRESS=true" >> $GITHUB_ENV echo "CCACHE_COMPRESSLEVEL=6" >> $GITHUB_ENV echo "CCACHE_MAXSIZE=400M" >> $GITHUB_ENV echo "::set-output name=timestamp::$(date -u -Iseconds)" - name: Set up ccache uses: actions/cache@v3 with: path: .ccache key: ${{matrix.os}}-${{matrix.hashmap}}-${{matrix.compiler}}-${{steps.env.outputs.timestamp}} restore-keys: ${{matrix.os}}-${{matrix.hashmap}}-${{matrix.compiler}} - name: Configure CMake project run: | cmake -S. \ -B_build \ -GNinja \ -DUSE_SANITIZERS:BOOL=ON \ -DLLVM_DIR:PATH="$(llvm-config-10 --cmakedir)" \ -D${HASHMAP}:PATH="$GITHUB_WORKSPACE/${{matrix.hashmap}}" - name: Build run: cmake --build _build - name: Run tests # TODO: turn off the detection of leaks, we're working on it run: ASAN_OPTIONS=detect_leaks=0 cmake --build _build --target check - name: ccache statistics run: ccache -s ================================================ FILE: .github/workflows/linux.yml ================================================ --- name: Linux CI on: [push, pull_request] jobs: build64: name: Ubuntu 64-bit strategy: fail-fast: false matrix: include: # Linux with GCC - {os: ubuntu-18.04, llvm: '3.9', compiler: gcc} - {os: ubuntu-18.04, llvm: '4.0', compiler: gcc} - {os: ubuntu-18.04, llvm: '5.0', compiler: gcc} - {os: ubuntu-18.04, llvm: '6.0', compiler: gcc} - {os: ubuntu-18.04, llvm: 7, compiler: gcc} - {os: ubuntu-18.04, llvm: 8, compiler: gcc} - {os: ubuntu-18.04, llvm: 9, compiler: gcc} - {os: ubuntu-20.04, llvm: 10, compiler: gcc} - {os: ubuntu-20.04, llvm: 11, compiler: gcc} - {os: ubuntu-20.04, llvm: 12, compiler: gcc} - {os: ubuntu-22.04, llvm: 13, compiler: gcc} - {os: ubuntu-22.04, llvm: 14, compiler: gcc} - {os: ubuntu-22.04, llvm: 14, compiler: gcc, type: Debug} # Linux with Clang - {os: ubuntu-18.04, llvm: '3.9', compiler: clang} - {os: ubuntu-18.04, llvm: '4.0', compiler: clang} - {os: ubuntu-18.04, llvm: '5.0', compiler: clang} - {os: ubuntu-18.04, llvm: '6.0', compiler: clang} - {os: ubuntu-18.04, llvm: 7, compiler: clang} - {os: ubuntu-18.04, llvm: 8, compiler: clang} - {os: ubuntu-18.04, llvm: 9, compiler: clang} - {os: ubuntu-20.04, llvm: 10, compiler: clang} - {os: ubuntu-20.04, llvm: 11, compiler: clang} - {os: ubuntu-20.04, llvm: 12, compiler: clang} - {os: ubuntu-22.04, llvm: 13, compiler: clang} - {os: ubuntu-22.04, llvm: 14, compiler: clang} - {os: ubuntu-22.04, llvm: 14, compiler: clang, type: Debug} runs-on: ${{matrix.os}} env: # for colours in ninja CLICOLOR_FORCE: 1 steps: - name: Checkout DG uses: actions/checkout@v3 - name: '[LLVM ${{matrix.llvm}}] Add repositories' if: matrix.llvm >= 15 run: | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-add-repository "deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{matrix.llvm}} main" - name: Install dependencies run: | sudo apt update sudo apt install ccache cmake ninja-build clang-${{matrix.llvm}} \ llvm-${{matrix.llvm}}-dev - name: Set environment id: env run: | if [[ "${{matrix.compiler}}" = "clang" ]]; then echo "CC=clang-${{matrix.llvm}}" >> $GITHUB_ENV echo "CXX=clang++-${{matrix.llvm}}" >> $GITHUB_ENV # force coloured output echo "CFLAGS=$CFLAGS -fcolor-diagnostics" >> $GITHUB_ENV echo "CXXFLAGS=$CXXFLAGS -fcolor-diagnostics" >> $GITHUB_ENV else echo "CC=gcc" >> $GITHUB_ENV echo "CXX=g++" >> $GITHUB_ENV # force coloured output echo "CFLAGS=$CFLAGS -fdiagnostics-color=always" >> $GITHUB_ENV echo "CXXFLAGS=$CXXFLAGS -fdiagnostics-color=always" >> $GITHUB_ENV fi # set up ccache sudo /usr/sbin/update-ccache-symlinks echo "/usr/lib/ccache" >> $GITHUB_PATH # Bionic does not create symlinks to versioned clang sudo ln -sfr /usr/bin/ccache /usr/lib/ccache/clang-${{matrix.llvm}} sudo ln -sfr /usr/bin/ccache /usr/lib/ccache/clang++-${{matrix.llvm}} echo "CCACHE_BASEDIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> $GITHUB_ENV echo "CCACHE_COMPRESS=true" >> $GITHUB_ENV echo "CCACHE_COMPRESSLEVEL=6" >> $GITHUB_ENV echo "CCACHE_MAXSIZE=400M" >> $GITHUB_ENV echo "::set-output name=timestamp::$(date -u -Iseconds)" - name: Set up ccache uses: actions/cache@v3 with: path: .ccache key: ${{matrix.os}}-${{matrix.llvm}}-${{matrix.compiler}}-${{matrix.type}}-${{steps.env.outputs.timestamp}} restore-keys: ${{matrix.os}}-${{matrix.llvm}}-${{matrix.compiler}}-${{matrix.type}} - name: '[Dynamic LLVM] Configure CMake project' run: | cmake -S. \ -B_build \ -GNinja \ -DCMAKE_BUILD_TYPE:STRING="${{matrix.type}}" \ -DUSE_SANITIZERS:BOOL=ON \ -DLLVM_DIR:PATH="/usr/lib/llvm-${{matrix.llvm}}/lib/cmake/llvm" # llvm-config-3.9 does not take --cmakedir yet! - name: '[Dynamic LLVM] Build' run: cmake --build _build - name: '[Dynamic LLVM] Run tests' # TODO: turn off the detection of leaks, we're working on it run: ASAN_OPTIONS=detect_leaks=0 cmake --build _build --target check - name: '[Static LLVM] Re-configure CMake project' run: | cmake -S. \ -B_build \ -DLLVM_LINK_DYLIB:BOOL=OFF cmake --build _build --target clean - name: '[Static LLVM] Build' run: cmake --build _build - name: '[Static LLVM] Run tests' # TODO: turn off the detection of leaks, we're working on it run: ASAN_OPTIONS=detect_leaks=0 cmake --build _build --target check - name: ccache statistics run: ccache -s # Warning: untested and incomplete # # build32: # name: Ubuntu 32-bit # runs-on: ubuntu-20.04 # container: ubuntu:latest # # strategy: # fail-fast: false # matrix: # compiler: [gcc, clang] # build_type: [Debug, Release] # # steps: # - uses: actions/checkout@v2 # - name: Install dependencies # run: | # dpkg --add-architecture i386 # apt update # apt install -y cmake ninja-build clang:i386 llvm-dev:i386 libc-dev:i386 # # - name: Set environment # run: | # CFLAGS="$CFLAGS -m32" # CXXFLAGS="$CXXFLAGS -m32" # # if [[ "${{matrix.compiler}}" = "clang" ]]; then # echo "CC=clang" >> $GITHUB_ENV # echo "CXX=clang++" >> $GITHUB_ENV # # # force coloured output # echo "CFLAGS=$CFLAGS -fcolor-diagnostics" >> $GITHUB_ENV # echo "CXXFLAGS=$CXXFLAGS -fcolor-diagnostics" >> $GITHUB_ENV # else # echo "CC=gcc" >> $GITHUB_ENV # echo "CXX=g++" >> $GITHUB_ENV # # # force coloured output # echo "CFLAGS=$CFLAGS -fdiagnostics-color" >> $GITHUB_ENV # echo "CXXFLAGS=$CXXFLAGS -fdiagnostics-color" >> $GITHUB_ENV # fi # # - name: Configure CMake project # run: | # cmake -Bbuild -S. \ # -GNinja \ # -DUSE_SANITIZERS=ON \ # -DCMAKE_BUILD_TYPE='${{matrix.build_type}}' # # - name: Build # run: ninja -C build # # - name: Run tests # # TODO: turn off the detection of leaks, we're working on it # run: ASAN_OPTIONS=detect_leaks=0 ninja check -C build ================================================ FILE: .github/workflows/mac.yml ================================================ --- name: macOS CI on: [push, pull_request] jobs: build: name: macOS strategy: fail-fast: false matrix: os: [macos-12] build: [Debug, RelWithDebInfo] runs-on: ${{matrix.os}} env: # for colours in ninja CLICOLOR_FORCE: 1 steps: - name: Checkout DG uses: actions/checkout@v3 - name: Install dependencies run: brew install ninja ccache llvm@14 - name: Set environment id: env run: | echo "CCACHE_BASEDIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> $GITHUB_ENV echo "CCACHE_COMPRESS=true" >> $GITHUB_ENV echo "CCACHE_COMPRESSLEVEL=6" >> $GITHUB_ENV echo "CCACHE_MAXSIZE=400M" >> $GITHUB_ENV echo "/usr/local/opt/ccache/libexec" >> $GITHUB_PATH echo "::set-output name=timestamp::$(date -u +%Y-%m-%dT%H:%M:%S%z)" - name: Set-up ccache uses: actions/cache@v3 with: path: .ccache key: ${{matrix.os}}-${{matrix.build}}-${{steps.env.outputs.timestamp}} restore-keys: ${{matrix.os}}-${{matrix.build}} - name: Configure CMake project run: | cmake -S. \ -B_build \ -GNinja \ -DCMAKE_BUILD_TYPE:STRING=${{matrix.build}} \ -DUSE_SANITIZERS:BOOL=ON \ -DLLVM_DIR:PATH="$($(brew --prefix llvm@14)/bin/llvm-config --cmakedir)" env: # for coloured output CFLAGS: -fcolor-diagnostics CXXFLAGS: -fcolor-diagnostics - name: Build run: cmake --build _build - name: Run tests # TODO: turn off the detection of leaks, we're working on it run: ASAN_OPTIONS=detect_leaks=0 cmake --build _build --target check - name: ccache statistics run: ccache -s ================================================ FILE: .github/workflows/svf.yml ================================================ --- name: DG + SVF on: [push, pull_request] jobs: Ubuntu: strategy: fail-fast: false matrix: os: [ubuntu-22.04] compiler: [gcc, clang] runs-on: ${{matrix.os}} env: # for colours in ninja CLICOLOR_FORCE: 1 steps: - name: Checkout DG uses: actions/checkout@v3 - name: Checkout SVF uses: actions/checkout@v3 with: ref: SVF-2.4 repository: SVF-tools/SVF path: svf - name: Checkout SVF test-suite uses: actions/checkout@v3 with: # ref corresponding to the SVF ref above ref: 2338ede904c1f46293b64ccf32feb09b3904401f repository: SVF-tools/Test-Suite path: svf/Test-Suite - name: Install dependencies run: | sudo apt update sudo apt install ccache cmake ninja-build clang-13 llvm-13-dev \ libz3-dev - name: Set environment id: env run: | if [[ "${{matrix.compiler}}" = "clang" ]]; then echo "CC=clang-13" >> $GITHUB_ENV echo "CXX=clang++-13" >> $GITHUB_ENV # force coloured output echo "CFLAGS=$CFLAGS -fcolor-diagnostics" >> $GITHUB_ENV echo "CXXFLAGS=$CXXFLAGS -fcolor-diagnostics" >> $GITHUB_ENV else echo "CC=gcc" >> $GITHUB_ENV echo "CXX=g++" >> $GITHUB_ENV # force coloured output echo "CFLAGS=$CFLAGS -fdiagnostics-color=always" >> $GITHUB_ENV echo "CXXFLAGS=$CXXFLAGS -fdiagnostics-color=always" >> $GITHUB_ENV fi # set up ccache sudo /usr/sbin/update-ccache-symlinks echo "/usr/lib/ccache" >> $GITHUB_PATH echo "CCACHE_BASEDIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> $GITHUB_ENV echo "CCACHE_COMPRESS=true" >> $GITHUB_ENV echo "CCACHE_COMPRESSLEVEL=6" >> $GITHUB_ENV echo "CCACHE_MAXSIZE=400M" >> $GITHUB_ENV echo "::set-output name=timestamp::$(date -u -Iseconds)" - name: Set up ccache uses: actions/cache@v3 with: path: .ccache key: ${{matrix.os}}-svf-${{matrix.compiler}}-${{steps.env.outputs.timestamp}} restore-keys: ${{matrix.os}}-svf-${{matrix.compiler}} - name: Build SVF run: | # Build directory name format is hard-coded in SVF tests... # do not build with -Werror (needed for GCC 11.2.0) sed -i 's/-Werror//' svf/CMakeLists.txt # WARNING: DO NOT SET CMAKE_BUILD_TYPE! (except Debug) # SVF expects that NDEBUG will never be defined! cmake -Ssvf \ -Bsvf/Release-build \ -GNinja \ -DLLVM_DIR:PATH="$(llvm-config-13 --cmakedir)" cmake --build svf/Release-build (cd svf/Release-build && \ PATH="$(llvm-config-13 --bindir):$PATH" \ ctest --progress --output-on-failure) - name: '[Dynamic LLVM] Configure CMake project' run: | cmake -S. \ -B_build \ -GNinja \ -DUSE_SANITIZERS:BOOL=ON \ -DLLVM_DIR:PATH="$(llvm-config-13 --cmakedir)" \ -DSVF_DIR:PATH="$GITHUB_WORKSPACE/svf/Release-build" - name: '[Dynamic LLVM] Build' run: cmake --build _build - name: '[Dynamic LLVM] Run tests' # TODO: turn off the detection of leaks, we're working on it run: ASAN_OPTIONS=detect_leaks=0 cmake --build _build --target check - name: '[Static LLVM] Re-configure CMake project' run: | cmake -S. \ -B_build \ -DLLVM_LINK_DYLIB:BOOL=OFF cmake --build _build --target clean - name: '[Static LLVM] Build' run: cmake --build _build - name: '[Static LLVM] Run tests' # TODO: turn off the detection of leaks, we're working on it run: ASAN_OPTIONS=detect_leaks=0 cmake --build _build --target check - name: ccache statistics run: ccache -s ================================================ FILE: .gitignore ================================================ # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Fortran module files *.mod # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app # cmake *.cmake *Makefile* # swp files *.swp *.swo *.swm # vim config files *.vimrc tags */tags */cscope.out *.swn *.dot *.ps # LLVM files *.bc *.sliced *.linked *.opt *.ll *.i tests/*-test tests/fuzzing/regressions/ # clangd .cache .clangd # pycache __pycache__ # C files in tools are test codes tools/*.c tools/*.bc tools/llvm-dg-dump tools/llvm-to-source tools/llvm-slicer git-version.h # build directory build # sourcetrail files dg.srctrl* compile_commands.json CMakeLists.txt.user* ================================================ FILE: .travis.yml ================================================ language: cpp sudo: true dist: trusty git: depth: 1 addons: apt: sources: # newer gcc and clang - ubuntu-toolchain-r-test - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main' key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main' packages: - libz-dev env: - LLVM=3.8 BUILD_TYPE=Release - LLVM=3.8 BUILD_TYPE=Debug - LLVM=4.0 BUILD_TYPE=Release - LLVM=4.0 BUILD_TYPE=Debug - LLVM=5.0 BUILD_TYPE=Release - LLVM=5.0 BUILD_TYPE=Debug compiler: - 'clang++' - 'g++' - 'g++-5' install: - git clone --depth 1 https://github.com/tomsik68/travis-llvm.git - cd travis-llvm - chmod +x travis-llvm.sh - ./travis-llvm.sh ${LLVM} - cd .. script: - cmake -DCMAKE_BUILD_TYPE="$BUILD_TYPE" -DUSE_SANITIZERS=ON . - make -j2 # for now turn off the detection of leaks, we're working on it - ASAN_OPTIONS=detect_leaks=0 make check -j2 notifications: email: false ================================================ FILE: CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.1) # FIXME: Unfortunately, C is (at least temporarily) required due to a bug # in LLVM 14. See https://github.com/llvm/llvm-project/issues/53950. project(dg LANGUAGES C CXX) include(CTest) # we need at least C++11 standard set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) OPTION(LLVM_DG "Support for LLVM Dependency graph" ON) OPTION(ENABLE_CFG "Add support for CFG edges to the graph" ON) OPTION(NO_EXCEPTIONS "Compile with -fno-exceptions (ON by default)" ON) if(NOT CMAKE_BUILD_TYPE) message(STATUS "Build type not set. Setting default.") set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "" FORCE) endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "RelWithDebInfo" "MinSizeRel" "Release") if (LLVM_DG) # for llvm dg we need cfg and postdom edges if (NOT ENABLE_CFG) message(STATUS "Enabling CFG edges due to llvm dg") endif() set(ENABLE_CFG ON) find_package(LLVM REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") message(STATUS "LLVM binaries: ${LLVM_TOOLS_BINARY_DIR}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LLVM_DIR}") include(LLVMConfig) include(AddLLVM) message(STATUS "LLVM include dir: ${LLVM_INCLUDE_DIRS}") message(STATUS "LLVM libraries dir: ${LLVM_LIBRARY_DIRS}") message(STATUS "LLVM definitions: ${LLVM_DEFINITIONS}") # if we were provided a path to custom sources # use that path if (LLVM_SRC_PATH) include_directories(SYSTEM ${LLVM_SRC_PATH}/include) message(STATUS "Looking for headers in given: ${LLVM_SRC_PATH}/include") else() include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) message(STATUS "Looking for headers in: ${LLVM_INCLUDE_DIRS}") endif() # if we were provided a path to custom build directory # use that if (LLVM_BUILD_PATH) link_directories(${LLVM_BUILD_PATH}/lib) # llvm-config.h include_directories(SYSTEM "${LLVM_BUILD_PATH}/include") message(STATUS "Looking for libraries in given: ${LLVM_BUILD_PATH}/lib") else() link_directories(${LLVM_LIBRARY_DIRS}) message(STATUS "Looking for libraries in: ${LLVM_LIBRARY_DIRS}") endif(LLVM_BUILD_PATH) add_definitions(${LLVM_DEFINITIONS}) option(LLVM_LINK_DYLIB "Link with LLVM dynamically" ON) if (LLVM_LINK_DYLIB) message(STATUS "LLVM linking: dynamic") if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.8") set(llvm LLVM-${LLVM_PACKAGE_VERSION}) else() # only LLVM 3.8+ provide unversioned library set(llvm LLVM) endif() else() message(STATUS "LLVM linking: static") if (${LLVM_PACKAGE_VERSION} VERSION_GREATER "3.4") llvm_map_components_to_libnames(llvm_analysis analysis) llvm_map_components_to_libnames(llvm_irreader irreader) llvm_map_components_to_libnames(llvm_bitwriter bitwriter) else() llvm_map_components_to_libraries(llvm_irreader irreader) llvm_map_components_to_libraries(llvm_bitwriter bitwriter) llvm_map_components_to_libraries(llvm_analysis analysis) endif() endif() # LLVM 10 and newer require at least c++14 standard if (${LLVM_PACKAGE_VERSION} VERSION_GREATER "9.0") set(CMAKE_CXX_STANDARD 14) option(USE_CXX14 "Use C++14 standard" ON) endif() endif(LLVM_DG) if (SVF_DIR) set(HAVE_SVF ON) add_definitions(-DHAVE_SVF) set(SVF_LIBDIR ${SVF_DIR}/lib) if (NOT SVF_INCLUDE) if (EXISTS "${SVF_DIR}/include/WPA/Andersen.h") set(SVF_INCLUDE ${SVF_DIR}/include) elseif (EXISTS "${SVF_DIR}/../include/WPA/Andersen.h") set(SVF_INCLUDE ${SVF_DIR}/../include) else() message(FATAL_ERROR "Did not find the directory with SVF headers") endif() endif() set(SVF_LIBS Svf Cudd) include_directories(SYSTEM ${SVF_INCLUDE}) link_directories(${SVF_LIBDIR} ${SVF_LIBDIR}/CUDD) if (NOT LLVM_LINK_DYLIB) if (${LLVM_PACKAGE_VERSION} VERSION_GREATER "3.4") llvm_map_components_to_libnames(llvm_transformutils transformutils) else() llvm_map_components_to_libraries(llvm_transformutils transformutils) endif() endif() message(STATUS "SVF dir: ${SVF_DIR}") message(STATUS "SVF libraries dir: ${SVF_LIBDIR}") message(STATUS "SVF include dir: ${SVF_INCLUDE}") message(STATUS "SVF libs: ${SVF_LIBS}") endif(SVF_DIR) if (TSL_HOPSCOTCH_DIR) set(HOPSCOTCH_DIR ${TSL_HOPSCOTCH_DIR}/include/) if (NOT EXISTS "${HOPSCOTCH_DIR}/tsl/hopscotch_map.h") message(FATAL_ERROR "Tessil hopscotch map NOT FOUND in ${TSL_HOPSCOTCH_DIR}" ) endif() include_directories(SYSTEM ${HOPSCOTCH_DIR}) message(STATUS "Found Tessil Hopscotch map in ${HOPSCOTCH_DIR}" ) message(STATUS "Adding include dir ${HOPSCOTCH_DIR}") add_definitions(-DHAVE_TSL_HOPSCOTCH) endif() if (ENABLE_CFG) add_definitions(-DENABLE_CFG) endif() message(STATUS "Using compiler: ${CMAKE_CXX_COMPILER}") # -------------------------------------------------- # Fuzzing # -------------------------------------------------- include(CheckCXXCompilerFlag) set(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer") check_cxx_source_compiles( "#include extern \"C\" int LLVMFuzzerTestOneInput(const void *, size_t) { return 0; }" HAS_FUZZER) set(CMAKE_REQUIRED_FLAGS "") option(ENABLE_FUZZING "Enable fuzzing tests" ${HAS_FUZZER}) if(NOT ENABLE_FUZZING) message(STATUS "Will NOT build fuzzing tests (requires Clang 6 or newer)") endif() # -------------------------------------------------- # clang-tidy # -------------------------------------------------- option(USE_CLANG_TIDY "Enable clang-tidy checks" OFF) if(USE_CLANG_TIDY) message(STATUS "Clang-tidy build enabled") # read config from .clang-tidy set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--config=") endif() # -------------------------------------------------- # Compiler flags # -------------------------------------------------- # explicitly add -std=c++11 (-std=c++14) and -fno-rtti # we have CMAKE_CXX_STANDARD, but for some reason it does not # put the -std=c++11 (-std=c++14) or -std=gnu++11 (-std=gnu++14) # to the flags on some systems. # For the -fno-rtti: LLVM still got problems with turning RTTI off... if (USE_CXX14) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -Wall -Wextra") if (NO_EXCEPTIONS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") endif() if (USE_SANITIZERS) set(CMAKE_REQUIRED_FLAGS "-fsanitize=undefined,address") # for linker check_cxx_compiler_flag("-fsanitize=undefined,address" sanitizers_work) set(CMAKE_REQUIRED_FLAGS "") if (sanitizers_work) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,address") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-sanitize-recover=all") add_definitions(-DUSING_SANITIZERS) else() message(WARNING "Used compiler does not support sanitizers or its support is incomplete.") endif() endif() # Debug Release RelWithDebInfo MinSizeRel. if (CMAKE_BUILD_TYPE STREQUAL "Debug") add_definitions(-DDEBUG_ENABLED) message(STATUS "Using compilation flags: ${CMAKE_CXX_FLAGS_DEBUG}") elseif (CMAKE_BUILD_TYPE STREQUAL "Release") message(STATUS "Using compilation flags: ${CMAKE_CXX_FLAGS_RELEASE}") elseif (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") message(STATUS "Using compilation flags: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") elseif (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") message(STATUS "Using compilation flags: ${CMAKE_CXX_FLAGS_MINSIZEREL}") endif () message(STATUS "Additional compilation flags: ${CMAKE_CXX_FLAGS}") include(GNUInstallDirs) message(STATUS "CMAKE_INSTALL_LIBDIR: \"${CMAKE_INSTALL_LIBDIR}\"") message(STATUS "CMAKE_INSTALL_INCLUDEDIR: \"${CMAKE_INSTALL_INCLUDEDIR}\"") include_directories(include) include_directories(lib) add_subdirectory(lib) add_subdirectory(tools) add_subdirectory(tests EXCLUDE_FROM_ALL) if(NOT LLVM_DG) set(INSTALL_EXCLUDE_PATTERNS PATTERN "llvm" EXCLUDE) endif() install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ${INSTALL_EXCLUDE_PATTERNS}) ================================================ FILE: Changelog ================================================ -- 3. 10. 2018 * The project was re-structured from src/ structure to lib/ and include/ structure. As a consequence, all public headers were moved to dg/ subdirectory, e.g. "llvm/LLVMDependenceGraph.h" is now "dg/llvm/LLVMDependenceGraph.h" * Renamed files: - llvm/Slicer.h -> dg/llvm/LLVMSlicer.h - llvm/analysis/PointsTo/PointsTo.h -> dg/llvm/analysis/PointsTo/PointerAnalysis.h - analysis/PointsTo/PointsToFlowSensitive.h -> dg/analysis/PointsTo/PointerAnalysisFS.h - analysis/PointsTo/PointsToFlowInsensitive.h -> dg/analysis/PointsTo/PointerAnalysisFI.h - analysis/PointsTo/PointsToWithInvalidate.h -> dg/analysis/PointsTo/PointerAnalysisFSInv.h * A new library libDGAnalysis.so was added. You must link to this library when linking with any dg library. ================================================ FILE: Dockerfile ================================================ # -------------------------------------------------- # Base container # -------------------------------------------------- FROM docker.io/ubuntu:jammy AS base RUN set -e # Install packages ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update RUN apt-get install -yq --no-install-recommends clang llvm # -------------------------------------------------- # Build container # -------------------------------------------------- FROM base as build # Can be used to specify which git ref to checkout ARG GIT_REF=master ARG GIT_REPO=mchalupa/dg # Install build dependencies RUN apt-get install -yq --no-install-recommends ca-certificates cmake git \ ninja-build llvm-dev python3 # Clone RUN git clone https://github.com/$GIT_REPO WORKDIR /dg RUN git fetch origin $GIT_REF:build RUN git checkout build # libfuzzer does not like the container environment RUN cmake -S. -GNinja -Bbuild -DCMAKE_INSTALL_PREFIX=/opt/dg \ -DCMAKE_CXX_COMPILER=clang++ -DENABLE_FUZZING=OFF RUN cmake --build build RUN cmake --build build --target check # Install RUN cmake --build build --target install/strip # ------------------------------------------------- # Release container # ------------------------------------------------- FROM base AS release COPY --from=build /opt/dg /opt/dg ENV PATH="/opt/dg/bin:$PATH" ENV LD_LIBRARY_PATH="/opt/dg/lib" # Verify it works RUN llvm-slicer --version ================================================ FILE: LICENSE ================================================ Copyright (c) 2015-2020 Marek Chalupa Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # DG [![Linux CI](https://github.com/mchalupa/dg/actions/workflows/linux.yml/badge.svg)](https://github.com/mchalupa/dg/actions/workflows/linux.yml) [![macOS CI](https://github.com/mchalupa/dg/actions/workflows/mac.yml/badge.svg)](https://github.com/mchalupa/dg/actions/workflows/mac.yml) DG is a library containing various bits for program analysis. However, the main motivation of this library is program slicing. The library contains implementation of a pointer analysis, data dependence analysis, control dependence analysis, and an analysis of relations between values in LLVM bitcode. All of the analyses target LLVM bitcode, but most of them are written in a generic way, so they are not dependent on LLVM in particular. Further, DG contains an implementation of dependence graphs and a [static program slicer](doc/llvm-slicer.md) for LLVM bitcode. Some documentation can be found in the [doc/](doc/) directory. * [Downloading DG](doc/downloading.md) * [Compiling DG](doc/compiling.md) * [Using llvm-slicer](doc/llvm-slicer.md) * [Other tools](doc/tools.md) ------------------------------------------------ You can find a high-level description of DG in [DG: a program analysis library](https://doi.org/10.1016/j.simpa.2020.100038) or [DG: Analysis and slicing of LLVM bitcode](https://www.fi.muni.cz/~xchalup4/dg_atva20_preprint.pdf) papers. More detailed information about dg is in the doc/ folder or in my [master thesis](http://is.muni.cz/th/396236/fi_m/thesis.pdf). You can write e-mails with issues to (or file issue in github). ================================================ FILE: dg.spec.rpkg ================================================ # vim: syntax=spec # Do out-of-source build by default on Fedora %undefine __cmake_in_source_build Name: {{{ git_dir_name }}} Version: {{{ git_dir_version }}} Release: 1%{?dist} Summary: Analyses, construction of dependence graphs and slicing of LLVM bitcode License: MIT URL: https://github.com/mchalupa/dg VCS: {{{ git_dir_vcs }}} Source: {{{ git_dir_archive }}} BuildRequires: clang BuildRequires: cmake BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: llvm-devel BuildRequires: make BuildRequires: ncurses-devel BuildRequires: python3 BuildRequires: zlib-devel Requires: clang Requires: llvm %description DG is a library containing various bits for program analysis. However, the main motivation of this library is program slicing. The library contains implementation of a pointer analysis, data dependence analysis, control dependence analysis, and an analysis of relations between values in LLVM bitcode. All of the analyses target LLVM bitcode, but most of them are written in a generic way, so they are not dependent on LLVM in particular. %prep {{{ git_dir_setup_macro }}} %build GIT_VERSION={{{ git rev-parse --short --sq HEAD }}} %cmake -DGIT_VERSION="$GIT_VERSION" %cmake_build %install %cmake_install %check %if 0%{?suse_version} %cmake_build -C %{__builddir} check %else %if 0%{?epel} %cmake_build check %else %cmake_build --target check %endif %endif %files %license LICENSE %doc doc/* %{_bindir}/* %{_includedir}/%{name} %{_libdir}/* ================================================ FILE: doc/CDA.md ================================================ # Control Dependence Analysis In DG, we implemented several algorithms for the computation of different control dependencies. These control dependencies are: - Standard (SCD) control dependence (Ferrante et al. [1]) - Non-termination sensitive control dependence (NTSCD) (Ranangath et al.[2]) - Decisive order dependence (DOD) (Ranangath et al.[2]) - [experimental/WIP] Strong control closures (Strong CC) (Danicic et al.[3]) ## Public API The class through which you can run and access the results of control dependence analysis is called `LLVMControlDependenceAnalysis` and is defined in [dg/llvm/ControlDependence/ControlDependence.h](../include/dg/llvm/ControlDependence/ControlDependence.h) The class takes an instance of `LLVMControlDependenceAnalysisOptions` in constructor. This object describes which analysis to run and whether to compute also interprocedural dependencies (see below). The public API of `LLVMControlDependenceAnalysis` contains several methods: * `run()` to run the analysis * `getDependencies()` to get dependencies of an instruction or a basic block (there are two polymorphic methods). As we compute intraprocedural dependencies on basic block level, these two method return different things. `getDependencies` for a basic block returns a set of values on which depend all the instructions in the basic block. `getDependencies` for instruction then returns additional dependencies, e.g., interprocedural. Therefore, if you want _all_ dependencies for an instruction, you should always query both, `getDependencies` for the instruction and also `getDependencies` for the basic block of the instruction. Note that the return value may be either an instruction or a basic block. If a basic block is returned as a dependence, it means that the queried value depends on the terminator instruction of the returned basic block. * `getDependent()` methods return values (instructions and blocks) that depend on the given instruction (block). They work similarly as `getDependencies` methods, just return dependent values instead of dependencies. If a block is returned, then all instructions of the block depend on the given value. * `getNoReturns()` return possibly no-returning points of the given function (those are usually calls to functions that may not return). If interprocedural analysis is disabled, returns always an empty vector. Then there are methods for closure-based algorithms, but these are mostly unimplemented (in fact, the Strong CC algorithm works, just these getter methods are not implemented yet). ## Interprocedural dependencies DG supports the computation of control dependencies that arise due to e.g., calling `abort()` from inside of a procedure. Consider this example: ```C void foo(int x) { if (x < 0) abort(); } int main() { int a = input(); foo(); assert(a > 0); } ``` In the example above, the assertion cannot be violated, because for values of `a` that would violate the assert the program is killed by the call to `abort`. That is, the assertion in fact depends on the if statement in the `foo` function. Such control dependencies between procedures are omitted by the classical algorithms. In DG, compute these dependencies by a standalone analysis that runs after computing intraprocedural control dependencies. Results of the interprocedural analysis are returned by `getDependencies` and `getDependent` along with results of the intraprocedural analysis (of course, only if interprocedural analysis is enabled by the options object). Also, NTSCD and DOD algorithms can be executed on interprocedural (inlined) CFG (ICFG). That is, a one big CFG that contains nodes for all basic blocks/instructions of the program and there are regular intraprocedural edges and also interprocedural edges going between calls and entry blocks/instructions and from returns to return-sites. For this functionality, use -cda-icfg. ## Tools There is the `llvm-cda-dump` tool that dumps the results of control dependence analysis. By default, it shows the results directly on LLVM bitcode. You can you the `-ir`switch to see the internal representation from the analyses. To select the analysis to run, use the `-cda` switch with one of these options: |opt | description | |----------------|---------------------------------------| |`scd` | standard CD (the default) | |`standard` | an alias for stanard | |`classic` | an alias for standard | |`ntscd` | non-termination sensitive CD | |`ntscd2` | NTSCD (a different implementation) | |`ntscd-ranganath` | Ranganath et al's algorithm for NTSCD (warning: it is incorrect) | |`dod` | Standalone DOD computation | |`dod-ranganath` | Ranganath et al's algorithm (the original algorithm was incorrect, this is a fixed version) | |`dod+ntscd` | NTSCD + DOD | |`scc` | Strong control closures | Note that `llvm-slicer` takes the very same options. There are also tools `llvm-ntscd-dump` specialized for showing internals and results of the NTSCD analysis, `llvm-cda-bench` that benchmarks a given list of analyses (the list is given without the `-cda` switch, e.g., `-ntscd -ntscd2 -dod`, see the help message) on a given program, and `llvm-cda-stress` that works like `llvm-cda-bench` with the difference that it generates and uses a random control flow graph and it works with only a subset of analyses (all except SCD). ## Other notes The algorithm for computing standard control dependencies does not have a generic implementation in DG as we heavily rely on LLVM in computation of post dominators. [1] Jeanne Ferrante, Karl J. Ottenstein, Joe D. Warren: The Program Dependence Graph and Its Use in Optimization. ACM Trans. Program. Lang. Syst. 9(3): 319-349 (1987) [2] Venkatesh Prasad Ranganath, Torben Amtoft, Anindya Banerjee, Matthew B. Dwyer, John Hatcliff: A New Foundation for Control-Dependence and Slicing for Modern Program Structures. ESOP 2005: 77-93 [3] Sebastian Danicic, Richard W.Barraclough, Mark Harman, John D.Howroyd, Ákos Kiss, Michael R.Laurence: A unifying theory of control dependence and its application to arbitrary program structures. Theoretical Computer Science, Volume 412, Issue 49, 2011, Pages 6809-6842 ================================================ FILE: doc/DDA.md ================================================ # Data Dependence Analysis DG contains the analysis of data dependencies (also called value-flow) based on constructing memory SSA form of the program. ## Public API The data dependence analysis class for LLVM is `LLVMDataDependenceAnalysis`. Its constructor takes the LLVM module, results of pointer analysis and optionally an instance of `LLVMDataDependenceAnalysisOptions`. Relevant methods from the public API are two polymorphic methods `getLLVMDefinitions`. One takes LLVM value which is required to read memory (can be checked by `isUse` method) and returns a vector of LLVM values that may have possibly written the values read by the given value. The other takes parameters `where`, `mem`, `off`, and `len` and returns all LLVM values that may write to the memory allocated by instruction or global variable `mem` at bytes from `off` to `off + len - 1` and the written value may be read at `where` (i.e., it has not been surely overwritten at `where` yet). ## Modeling external (undefined) functions The class `LLVMDataDependenceAnalysisOptions` has the possibility of registering models for functions. If the analysis then hits a call of the given function, it uses this model instead of calling the function (if the function is defined in the module) or instead of assuming that the function may do anything. The methods that take care of registering models of functions are `functionModelAddDef` and `functionModelAddUse`. These methods take the name of the modelled function and a tripple `(argidx, offset, len)` which means that the function defines/uses the memory pointed by the `argidx`-th argument (beginning at 0) and define `len` bytes from the memory beginning at `argidx + offset`. If `len` (`offset`, resp.) are of type `Offset`, these are interpreted as constant numbers. However, if those are of type `unsigned`, those are interpreted as indexes of arguments (the same as `argidx`) meaning that the real number of bytes and offset is given by the argument of the called function. If the argument is not a constant, it is taken as UNKNOWN. For example, ```C functionModelAddUse("memset", {0, Offset(0), 2})` ``` tell the analysis that `memset` function defines the memory pointed by the first argument (with index 0) and this memory is defined from the byte where the first argument points. Also, only the number of bytes specified by the third argument (with index 2) are used. For the code ```C int array[10]; memset(array + 2, 0, 20); ``` The analysis will create a model that tells that this call to `memset` defines bytes 8 - 27 of `array` (given that the size of int is 4 bytes).Another examples of using these functions can be found in [LLVMDataDependenceAnalysisOptions.h](../include/dg/llvm/DataDependence/LLVMDataDependenceAnalysisOptions.h). ## Tools There is `llvm-dda-dump` that dumps the results of data dependence analysis. If dumped to .dot file (`-dot` option) the computed memory SSA along with def-use chains is shown. ================================================ FILE: doc/PTA.md ================================================ # Pointer Analysis in DG Pointer analysis (PTA) implementation in DG consists of a general part and LLVM part. The general part include a program representation (graph) and the pointer analysis algorithm that runs on the graph. The LLVM part takes care of building the pointer graph from the LLVM module and translating results from the analysis to consumers of LLVM bitcode (i.e., if we ask for points-to set of a LLVM value, we get a set of LLVM values and not the analysi's internal nodes). The program representation (`PointerGraph`) is a graph whose nodes (`PSNode`) contain information about pointer handlings, e.g., casts, storing and loading to/from memory, shifting, etc. Further, the graph is subdivided into subgraphs (`PointerSubgraph`) that correspond to procedures. Once we build the pointer graph, we can run an analysis on it. In DG, the pointer analysis class has virtual `getMemoryObjects` method whose definition changes the behavior of the analysis (along with auxiliary `processefore` and `processAfter`). Once the `run` method of pointer analysis is invoked, the analysis computes points-to sets of nodes (that correspond to top-level values in LLVM) until fixpoint is reached. We have implemented flow-sensitive (data-flow) and flow-insensitive (Andersen's-like) pointer analysis (this one is used by default). ## LLVM pointer analysis Files from [dg/llvm/PointerAnalysis/](../include/dg/llvm/PointerAnalysis/) The pointer analysis for LLVM is provided by the `LLVMPointerAnalysis` class. This class can have different implementations, all of them complying with a basic public API: ##### `hasPointsTo` returns true if 1) PTA has any points-to set for the given value 2) the points-to set is non-empty``` ##### `getLLVMPointsTo` returns points-to set (object of the class `LLVMPointsToSet`, see below) for the given value. If `hasPointsTo` would be false for the given value, points-to set containging the only element `unknown` is returned. ##### `getLLVMPointsToChecked` returns points-to set (object of the class `LLVMPointsToSet`) for the given value and a bool which corresponds with the result of `hasPointsTo`. The boolean returned is good for checking whether the `unknown` pointer in the points-to set (if any) is a result of the analysis (e.g., a pointer returned from an undefined function) or is there because the analysis has no information about the queried value. ##### `getAccessedMemory` is a wrapper around getLLVMPointsTo that returns `LLVMMemoryRegionSet`. This object represents a set of tripples (memory, offset, length) describing the regions of memory accessed by the given instruction (e.g., store or load). `LLVMPointsToSet` is an object that yields `LLVMPointer` objects upon iteration. Each `LLVMPointer` object is a pair of LLVM `Value` and `Offset` containing the allocation that allocated the pointed memory and the offset into the memory. `LLVMPointsToSet` has also methods `hasUnknown`, `hasNull`, and `hasInvalidated` that return true if the points-to set contains `unknown`, `null`, or `invalidated` (i.e., pointing to freed or destroyed memory) element. Note that these elements are not physically present in the points-to set as there are no LLVM Values that would represent them (and thus could be returned in LLVMPointer). ## Tools Results of pointer analysis can be dumped by the `llvm-pta-dump` tool which can be found in `tools/` directory. Possible options are: Option | Values | Description ----------------------|-------------|------------- `-pta` | fi, fs, inv, svf | Type of analysis - flow-insensitive, flow-sensitive, flow-sensitive with tracking invalidated memory, and SVF (if available) `-pta-field-sensitive` | BYTES | Set field sensitivity: how many bytes to track on each object `-callgraph` | | Dump also call graph `-callgraph-only` | | Dump only call graph `-iteration` | NUM | How many iterations to perform (for debugging) `-graph-only` | | Do not run PTA, just build and dump the pointer graph `-stats` | | Dump statistics `-entry` | FUN | Set entry function to FUN `-dbg` | | Show debugging messages `-ir` | | Dump internal representation of the analysis `-c-lines` | | Dump output on the level of C lines (needs debug info) `-dot` | | Dump IR and results of the analysis to .dot file `-v` `-vv` | | Verbose output Further, there is the tool `llvm-pta-ben` for evaulation of files annotated according to the [PTABen](https://github.com/SVF-tools/PTABen) project, and `llvm-pta-compare` that compares results different pointer analyses. ================================================ FILE: doc/README.md ================================================ # DG library DG is a C++ library containing bits for building various static program analyses. The main part of the library aims at building dependence graph and program slicing. In particular, DG contains an implementation of static program slicer for LLVM bitcode. #### Supported operating systems We develop and target DG on GNU/Linux. The project should be compilable on OSX, though there were some issues in the past (issue [#230](https://github.com/mchalupa/dg/issues/230)). There were also some unresolved attempts to compile DG on Windows. Although the code does not use any compiler-specific or non-portable features, so it should be compilable on Windows, the compilation was failing due to problems with linking to LLVM libraries (issues [#196](https://github.com/mchalupa/dg/issues/196) and [#315](https://github.com/mchalupa/dg/issues/315)). ## Analyses - [Pointer analysis](PTA.md) - [Data dependence analysis](DDA.md) - [Control dependence analysis](CDA.md) - [Value-relations analysis](VRA.md) ## Tools - [llvm-slicer](llvm-slicer.md) - [Other tools](tools.md) ## External Libraries - [SVF](SVF.md) ================================================ FILE: doc/SVF.md ================================================ # Integration of SVF into DG DG can use pointer anlysis from the SVF project. This analysis should scale much more better than ours, however, our analysis can be more precise in some cases. ## Building DG with SVF To use SVF with DG, you first needs a build of [SVF](https://github.com/SVF-tools/SVF). Build the project according its instructions. To configure DG with SVF, setup `SVF_DIR` variable to point to the build of SVF: ``` cmake . -DSVF_DIR=/path/to/svf/build ``` During configuration, cmake should inform you about the found SVF build: ```cmake -- SVF dir: /home/user/SVF/Debug-build -- SVF libraries dir: /home/user/SVF/Debug-build/lib -- SVF include dir: /home/user/SVF/Debug-build/../include -- SVF libs: LLVMSvf;LLVMCudd ``` In cases of out-of-source build of SVF you may want to manually specify the varable for include directory: ``` cmake . -DSVF_DIR=/path/to/svf/build -DSVF_INCLUDE=/path/to/svf/include ``` `SVF_DIR` must point to a directory that contains the `lib` subdirectory with libraries. `SVF_INCLUDE` must point to directly to a directory that contains the header files. ## Using DG with SVF DG now integrates only pointer analysis from SVF. To use SVF from C++ API, just specify in the `LLVMPointerAnalysisOptions` object that the analysis is of type `LLVMPointerAnalysisOptions::AnalysisType::svf`. For tools, the switch that turns on SVF pointer analysis is `-pta svf`, for example: ``` tools/llvm-slicer -c foo -pta svf test.ll ``` ================================================ FILE: doc/compiling.md ================================================ # Compiling DG from sources ## Requirements DG needs LLVM 3.4 or higher. Further requirements are `cmake`, `make`, `g++` or `clang++` in a version that supports at least C++11 standard. And, of course, `git` for downloading the project. On some systems, also `zlib` is required. For compilation of files into LLVM, we need also `clang` compiler. To run slicing tests and some of the tools, you need also an installation of `python`. On Ubuntu, you install the dependencies with: ``` apt install git cmake make llvm zlib1g-dev clang g++ python3 ``` On ArchLinux, the command for installing the dependencies is the following: ``` pacman -S git cmake make llvm clang gcc python ``` On CentOS/RHEL/Fedora, the command for installing the dependencies is the following: ``` dnf install git cmake make zlib-devel llvm-devel gcc-c++ ncurses-devel ``` You can use also LLVM compiled from sources (see below). ## Building docker image The DG repository contains a prepared Dockerfile that builds DG under Ubuntu 20.04. To build the docker image, go into the top-level project's directory (the one containing Dockerfile) and run: ``` docker build . --tag dg:latest docker run -ti dg:latest ``` The Dockerfile installs only the prerequisities for dg. If you need anything else to try out dg (e.g., vim or emacs), you must install it manually inside the image. ## Compiling DG The first step is to clone the repository to your machine: ``` git clone https://github.com/mchalupa/dg cd dg ``` Once you have the project cloned, you need to configure it. When LLVM is installed on your system in standard paths, the configuration should be as easy as calling `cmake`: ``` cmake . ``` or ``` mkdir build cd build cmake .. ``` However, if you have LLVM installed in non-standard paths, or you have several versions of LLVM and want to use a particular one, you must manually specify path to the installation: ``` cmake -DLLVM_SRC_PATH=/path/to/src -DLLVM_BUILD_PATH=/path/to/build -DLLVM_DIR=path/to/llvm/share/llvm/cmake . ``` LLVM\_DIR is an environment variable used by LLVM to find cmake config files (it points to the build or install directory), LLVM\_SRC\_DIR is a variable that tells cmake where to look for llvm's sources and it is used to override include paths. The same holds for LLVM\_BUILD\_PATH that is used to override library paths. Usually, you don't need to specify all these variables: LLVM\_DIR variable is useful if there is any collision (i.e. there are more versions of LLVM installed) and you want to use a particular build of LLVM. In that case, define the LLVM\_DIR variable to point to the directory where are the config files of the desired version (`$PREFIX/share/llvm/cmake` or `$PREFIX/lib/cmake/llvm/` for newer versions of LLVM -- for system installations, `PREFIX` is usually set to `/usr`). If you have LLVM compiled from sources but not installed anywhere, you may need to use LLVM\_SRC\_PATH and LLVM\_BUILD\_PATH variables to specify the directory with sources and build. As an example, suppose you have LLVM built in /home/user/llvm-build from sources in /home/user/llvm-src. Then the following configuration should work: ``` cmake -DLLVM_SRC_PATH=/home/user/llvm-src -DLLVM_BUILD_PATH=/home/user/llvm-build -DLLVM_DIR=/home/user/llvm-build/share/llvm/cmake . ``` The LLVM is linked dynamically by default. This behaviour can be toggled by turning the `LLVM_LINK_DYLIB` option `OFF`. Note that some additional packages might be required than those listed above when linking statically. If you want to build the project with debugging information and assertions, you may specify the build type by adding `-DCMAKE_BUILD_TYPE=Debug` during configuration. Also, you may enable building with sanitizers by adding `-DUSE_SANITIZERS=ON`. After configuring the project, usual `make` takes place: ``` make -j4 ``` In this documentation, you can find also some reports of how we compiled DG on different Linux systems with the system LLVM packages. These documents describe just the one-time experience and are not maintained. Therefore, the reports may be out-of-date: - [Compiling on Ubuntu Trusty](compiling_ubuntu_trusty.md) - [Compiling on Ubuntu Xenial](compiling_ubuntu_xenial.md) ## Building with SVF support If you want to build DG with the support of the [SVF](https://github.com/SVF-tools/SVF) library, you must specify `SVF_DIR` variable to point to the build of SVF. For more information, see [documentation for SVF](SVF.md). ## Testing You can run tests with `make check`. The command runs unit tests and also tests of slicing LLVM bitcode in several different configurations, so it may take a while. If your compiler supports `libFuzzer`, fuzzing tests are compiled and run as well. ================================================ FILE: doc/compiling_ubuntu_trusty.md ================================================ # The experience with compiling DG on Ubuntu Trusty This is my experience with compiling DG on (a clean installation of) Ubuntu Trusty for different versions of LLVM. To summarize, compiling DG with a custom build of LLVM goes fine on Ubuntu Trusty. Using system LLVM packages does not work at all. The only way how to compile DG without compiling also LLVM is to use our packages that we use in CI. If LLVM is compiled from sources, it should be enough to set `LLVM_DIR` (and possibly `LLVM_SRC_DIR` and `LLVM_BUILD_DIR` to the right directories. The LLVM 3.4-3.8 packages from the system repositories unfortunately contain broken cmake files. Not only the config file is named `LLVM-Config.cmake` instead of `LLVMConfig.cmake` for some LLVM version,but there is also broken the mapping to LLVM libraries. The configuration with system LLVM 3.9 goes smoothly, but the compilation fails with this error: ``` /usr/lib/llvm-3.9/lib/libLLVMCore.a(AsmWriter.cpp.o): unrecognized relocation (0x2a) in section `.text._ZN4llvm24AssemblyAnnotationWriterD2Ev' ``` Greater versions of LLVM are not available from the repositories. ## Building with LLVM package from our CI If you do not want to compile LLVM from sources, for LLVM 3.8, 4, and 5 you can use the packages that we use in our CI: ``` git clone --depth 1 https://github.com/tomsik68/travis-llvm.git cd travis-llvm chmod +x travis-llvm.sh ./travis-llvm.sh 3.8 # change 3.8 to 4 or 5 if wanted ``` Now we can proceed normally with configuration and compilation: ``` cd dg cmake . -DLLVM_DIR=/usr/share/llvm-3.8/cmake make -j4 ``` ================================================ FILE: doc/compiling_ubuntu_xenial.md ================================================ # The experience with compiling DG on Ubuntu Trusty This is my experience with compiling DG on (a clean installation of) Ubuntu Xenial for different versions of LLVM. Compiling DG with LLVM built from sources should work fine, so here I focus only on the compilation with LLVM from the repositories packages. First of all, install the dependencies. ``` apt update apt install git cmake make zlib1g-dev clang g++ python3 ``` ## LLVM 3.8 The default LLVM is 3.8 which you can install with: ``` apt install llvm ``` Unfortunately, it still suffers from the broken cmake files as in Ubuntu Trusty (the files are in `/usr/share/llvm-3.8/cmake/`, but cmake is instructed to look for the configuration files in `/usr/share/llvm/cmake/`. So for LLVm 3.8, the only option is to build LLVM from sources or use our CI package (see [Compiling on Ubuntu Trusty](compiling_ubuntu_trusty.md) page). ## LLVM >= 3.9 Compiling DG with system LLVM 3.9 and higher (Xenial has packages for LLVM 3.9, 4.0, 5.0, 6.0, and 8.0) should work out of the box. After the installation of prerequisities, just install LLVM, configure DG and compile (replace `-3.9` with the desired version of LLVM): ``` apt install llvm-3.9 cmake . # you may need to use -DLLVM_DIR=/usr/lib/llvm-3.9/cmake make -j2 ``` Don't forget to compile source code to LLVM with the right version of clang: ``` apt install clang-3.9 ``` The binaries `clang`, `llvm-link`, `opt`, and `lli` (for running slicing tests) may have the suffix `-3.9`, so you may need to create symbolic links with names without the suffix to successfully run tests. ================================================ FILE: doc/downloading.md ================================================ # Getting pre-compiled DG You can obtain pre-compiled DG project in several forms. ## Docker image You can download the image from [Docker Hub](https://hub.docker.com/r/mchalupa/dg). The image contains, apart from DG, also vim and emacs editors and clang, so that you can try dg out. (Note that this image is not being updated regularly). Alternatively, the root folder of dg contains a Dockerfile which allows you to build a docker image with dg installed. Just run these commands from the dg's root directory: ``` docker build . --tag dg:latest docker run -ti dg:latest ``` Note that the locally built image does not contain either vim or emacs, so you must install one of them if you need. ## Binary Packages We have packed DG for several systems. The packages contain only the library and `llvm-slicer`. Other tools are not included. ### Ubuntu package A binary package for Ubuntu 18.04 can be found in [Releases](https://github.com/mchalupa/dg/releases/tag/v0.9-pre). ### Archlinux AUR package There is also the [dg-git](https://aur.archlinux.org/packages/dg-git/) AUR package for Archlinux users. ================================================ FILE: doc/llvm-slicer.md ================================================ # llvm-slicer DG project contains a static slicer for LLVM bitcode. The slicer supports backward and forward (experimental) slicing. It is designed and tested on slicing code generated from sequential C programs. However, there is an experimental support for parallel programs and it should handle bitcode generated from other languages in many cases. There is a section on using the slicer with bitcode generated from C++ at the end of this file. ### Using the llvm-slicer The compiled `llvm-slicer` can be found in the `tools/` subdirectory. First, you need to compile your program into LLVM IR (make sure you are using the correct version of LLVM binaries if you have more than one): ``` clang -c -emit-llvm source.c -o bitcode.bc ``` If the program is split into more source files (exactly one of them must contain main), you must compile each of them separately (as above) and then link the bitcodes together using `llvm-link`: ``` llvm-link bitcode1.bc bitcode2.bc ... -o bitcode.bc ``` Now, you're ready to slice the program: ``` ./llvm-slicer -c slicing_criterion bitcode.bc ``` The `slicing_criterion` is either a call-site of a function or `ret` to slice with respect to the return value of the main function. Alternatively, if the program was compiled with the `-g` option, you can also use `line:variable` as slicing criterion. Slicer will then try to find a use of the variable on the provided line and mark this use, if found, as a slicing criterion. If no line is provided (e.g. `:x`), then the variable is considered to be global variable. You can provide a comma-separated list of slicing criterions, e.g.: `-c crit1,crit2,crit3`. More about specifying slicing criteria can be found [later](#slicing-criteria) in this document. You can view the dependence graph that was used to slice the bitcode by exporting it into .dot file. To achieve this, use `-dump-dg` switch with `llvm-slicer` or a stand-alone tool like `llvm-dg-dump` (this one is deprecated, but should still work): ``` ./llvm-dg-dump bitcode.bc > file.dot ``` You can highlight nodes from the dependence graph that will be in the slice using the `-mark` switch: ``` ./llvm-dg-dump -mark slicing_criterion bitcode.bc > file.dot ``` When using `-dump-dg` with `llvm-slicer`, the nodes should be already highlighted. Also a .dot file with the sliced dependence graph is generated (similar behaviour can be achieved with `llvm-dg-dump` using the `-slice` switch). If the dependence graph is too big to be displayed using .dot files, you can debug/see the slice right from the LLVM language. Just pass `-annotate` option to the `llvm-slicer` and it will store readable annotated LLVM in `file-debug.ll` (where `file.bc` is the name of file being sliced). There are more options (try `llvm-slicer -help` for show all of them), but the most interesting is probably the `-annotate slice`: ``` ./llvm-slicer -c crit -annotate slice code.bc ``` The content of `code-debug.ll` will look like this: ```LLVM ;