From 87ba723b4a8e9a71c53f82ffb6ef637700eae825 Mon Sep 17 00:00:00 2001 From: Langston Barrett Date: Tue, 1 Nov 2022 11:28:34 -0400 Subject: [PATCH] LLVM 15 --- .github/workflows/ci.yml | 9 +++++-- FactGenerator/include/Factgen.hpp | 2 +- FactGenerator/include/TypeAccumulator.hpp | 6 +++++ FactGenerator/src/Globals.cpp | 4 +++ FactGenerator/src/InstructionVisitor.cpp | 12 +++++++++ FactGenerator/src/Main.cpp | 10 +++++--- FactGenerator/src/TypeVisitor.cpp | 22 ++++++++++++----- doc/index.rst | 2 +- doc/overview.rst | 8 +++--- docker/dev.dockerfile | 9 ++++--- docker/dist.dockerfile | 30 ++++++++++++++++++++--- test/conftest.py | 2 +- 12 files changed, 91 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29efba1..2b18b4b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,8 @@ env: SPHINXOPTS: "-W --keep-going" # This will be empty on events that aren't pull requests. ACTUAL_GITHUB_SHA_ON_PULL_REQUEST: "${{ github.event.pull_request.head.sha }}" - # TODO(#12): Upgrade to Ubuntu 22.04 (jammy), Clang 15, LLVM 15 + # TODO(#12, #113): Upgrade to Clang 15, LLVM 15. + # # See also the matrix of the build job. # # NOTE[Clang+LLVM]: If the Clang version outstrips the LLVM version, the tests @@ -59,7 +60,7 @@ jobs: llvm_version: "12" ubuntu_version: "20.04" ubuntu_name: "focal" - - clang_version: "14" + - clang_version: "15" llvm_version: "13" ubuntu_version: "22.04" ubuntu_name: "jammy" @@ -67,6 +68,10 @@ jobs: llvm_version: "14" ubuntu_version: "22.04" ubuntu_name: "jammy" + - clang_version: "15" + llvm_version: "15" + ubuntu_version: "22.04" + ubuntu_name: "jammy" env: LLVM_MAJOR_VERSION: ${{ matrix.llvm_version }} CLANG_VERSION: ${{ matrix.llvm_version }} diff --git a/FactGenerator/include/Factgen.hpp b/FactGenerator/include/Factgen.hpp index df91bee..93488c0 100644 --- a/FactGenerator/include/Factgen.hpp +++ b/FactGenerator/include/Factgen.hpp @@ -29,7 +29,7 @@ void factgen( const boost::filesystem::path &outputDir, const llvm::Optional &signatures, const ContextSensitivity &context_sensitivity, - std::string delim); + const std::string &delim); } // namespace cclyzer #endif /* FACT_GENERATOR_HPP__ */ diff --git a/FactGenerator/include/TypeAccumulator.hpp b/FactGenerator/include/TypeAccumulator.hpp index 6c1b835..7a87df3 100644 --- a/FactGenerator/include/TypeAccumulator.hpp +++ b/FactGenerator/include/TypeAccumulator.hpp @@ -55,7 +55,13 @@ class cclyzer::llvm_utils::TypeAccumulator { if (elementType->isArrayTy()) { visitType(elementType->getArrayElementType()); } else if (elementType->isPointerTy()) { +#if LLVM_VERSION_MAJOR > 14 + if (!llvm::cast(elementType)->isOpaque()) { + visitType(elementType->getPointerElementType()); + } +#else visitType(elementType->getPointerElementType()); +#endif } else if (elementType->isStructTy()) { visitStructType(elementType); } else if (elementType->isVectorTy()) { diff --git a/FactGenerator/src/Globals.cpp b/FactGenerator/src/Globals.cpp index e26334d..12feca1 100644 --- a/FactGenerator/src/Globals.cpp +++ b/FactGenerator/src/Globals.cpp @@ -66,7 +66,11 @@ void FactGenerator::writeGlobalVar( // Serialize global variable properties refmode_t visibility = refmode(gv.getVisibility()); refmode_t linkage = refmode(gv.getLinkage()); +#if LLVM_VERSION_MAJOR > 14 + refmode_t varType = recordType(gv.getType()); +#else refmode_t varType = recordType(gv.getType()->getElementType()); +#endif refmode_t thrLocMode = refmode(gv.getThreadLocalMode()); // Record demangled variable name diff --git a/FactGenerator/src/InstructionVisitor.cpp b/FactGenerator/src/InstructionVisitor.cpp index 97270a5..62ded59 100644 --- a/FactGenerator/src/InstructionVisitor.cpp +++ b/FactGenerator/src/InstructionVisitor.cpp @@ -320,8 +320,12 @@ void InstructionVisitor::visitAllocaInst(const llvm::AllocaInst &AI) { if (AI.isArrayAllocation()) writeInstrOperand(pred::alloca::size, iref, AI.getArraySize()); +#if LLVM_VERSION_MAJOR > 14 + gen.writeFact(pred::alloca::alignment, iref, llvm::Log2(AI.getAlign())); +#else if (AI.getAlignment()) gen.writeFact(pred::alloca::alignment, iref, AI.getAlignment()); +#endif } void InstructionVisitor::visitLoadInst(const llvm::LoadInst &LI) { @@ -331,8 +335,12 @@ void InstructionVisitor::visitLoadInst(const llvm::LoadInst &LI) { if (LI.isAtomic()) writeAtomicInfo(iref, LI); +#if LLVM_VERSION_MAJOR > 14 + gen.writeFact(pred::load::alignment, iref, llvm::Log2(LI.getAlign())); +#else if (LI.getAlignment()) gen.writeFact(pred::load::alignment, iref, LI.getAlignment()); +#endif if (LI.isVolatile()) gen.writeFact(pred::load::is_volatile, iref); } @@ -370,8 +378,12 @@ void InstructionVisitor::visitStoreInst(const llvm::StoreInst &SI) { if (SI.isAtomic()) writeAtomicInfo(iref, SI); +#if LLVM_VERSION_MAJOR > 14 + gen.writeFact(pred::store::alignment, iref, llvm::Log2(SI.getAlign())); +#else if (SI.getAlignment()) gen.writeFact(pred::store::alignment, iref, SI.getAlignment()); +#endif if (SI.isVolatile()) gen.writeFact(pred::store::is_volatile, iref); } diff --git a/FactGenerator/src/Main.cpp b/FactGenerator/src/Main.cpp index 4c2e8aa..c7377db 100644 --- a/FactGenerator/src/Main.cpp +++ b/FactGenerator/src/Main.cpp @@ -29,7 +29,7 @@ void cclyzer::factgen( const fs::path &outputDir, const llvm::Optional &signatures, const ContextSensitivity &context_sensitivity, - std::string delim) { + const std::string &delim) { using cclyzer::FactGenerator; using cclyzer::FactWriter; @@ -42,7 +42,7 @@ void cclyzer::factgen( llvm::SMDiagnostic err; // Create fact writer - FactWriter writer(outputDir, std::move(delim)); + FactWriter writer(outputDir, delim); // Create CSV generator FactGenerator &gen = FactGenerator::getInstance(writer); @@ -96,12 +96,14 @@ auto main(int argc, char *argv[]) -> int { // Alternate version that doesn't use templates so that the python bindings work void factgen2( - std::vector files, const fs::path &outputDir, std::string delim) { + std::vector files, + const fs::path &outputDir, + const std::string &delim) { cclyzer::factgen( files.begin(), files.end(), outputDir, llvm::Optional(), INSENSITIVE, - std::move(delim)); + delim); } diff --git a/FactGenerator/src/TypeVisitor.cpp b/FactGenerator/src/TypeVisitor.cpp index b7aecca..2476776 100644 --- a/FactGenerator/src/TypeVisitor.cpp +++ b/FactGenerator/src/TypeVisitor.cpp @@ -90,25 +90,35 @@ void TypeVisitor::visitType(const llvm::Type *type) { #if LLVM_VERSION_MAJOR > 11 case llvm::Type::X86_AMXTyID: // TODO: handle this type break; +#endif +#if LLVM_VERSION_MAJOR > 14 + case llvm::Type::DXILPointerTyID: // TODO: handle this type + break; #endif } } void TypeVisitor::visitPointerType(const PointerType *ptrType) { - const llvm::Type *elemType = ptrType->getPointerElementType(); - refmode_t typeId = gen.refmode(*ptrType); - refmode_t elemTypeId = gen.refmode(*elemType); // Record pointer type entity gen.writeFact(pred::ptr_type::id, typeId); - // Record pointer element type - gen.writeFact(pred::ptr_type::component_type, typeId, elemTypeId); - // Record pointer address space if (unsigned addressSpace = ptrType->getPointerAddressSpace()) gen.writeFact(pred::ptr_type::addr_space, typeId, addressSpace); + + // Record pointer element type +#if LLVM_VERSION_MAJOR > 14 + auto cond = !ptrType->isOpaque(); +#else + auto cond = true; +#endif + if (cond) { + const llvm::Type *elemType = ptrType->getPointerElementType(); + refmode_t elemTypeId = gen.refmode(*elemType); + gen.writeFact(pred::ptr_type::component_type, typeId, elemTypeId); + } } void TypeVisitor::visitArrayType(const ArrayType *arrayType) { diff --git a/doc/index.rst b/doc/index.rst index d63bde0..0bc27cc 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -26,7 +26,7 @@ is highly parallel. cclyzer++ was derived from `cclyzer`_. Documentation is also available `online`_. -cclyzer++ is not currently actively developed or maintained by Galois, Inc. +cclyzer++ is actively developed and maintained by Galois, Inc. .. note:: You may also want to peruse the `Release Announcement diff --git a/doc/overview.rst b/doc/overview.rst index fa64ec3..7421b8f 100644 --- a/doc/overview.rst +++ b/doc/overview.rst @@ -66,7 +66,8 @@ Comparison to cclyzer As mentioned above, cclyzer++ is based on cclyzer. The major differences are that cclyzer++ -* supports LLVM 10 through 14 +* :ref:`supports LLVM 10 through 14 `, with limited support for + LLVM 15. * is implemented in Soufflé rather than LogicBlox * has :ref:`a C++ interface `, rather than a Python one * has runtime-configurable context-sensitivity and heap-cloning @@ -109,8 +110,8 @@ LLVM Library Version .. TODO(lb): Policy for supporting different LLVM versions cclyzer++ currently builds against LLVM 14 by default and can be built with -previous versions 13 through 10. There are `plans `_ to support -LLVM 15. +previous versions 13 through 10. cclyzer++ can be built with LLVM 15, but +the analysis `does not yet support opaque pointers `_. Development Tools ***************** @@ -121,4 +122,5 @@ build with Clang 15. .. _tutorial: http://yanniss.github.io/points-to-tutorial15.pdf .. _llvmver: https://github.com/GaloisInc/cclyzerpp/issues/12 +.. _opaque: https://github.com/GaloisInc/cclyzerpp/issues/113 .. _semver: https://semver.org/spec/v2.0.0.html diff --git a/docker/dev.dockerfile b/docker/dev.dockerfile index b98b8ad..b251e32 100644 --- a/docker/dev.dockerfile +++ b/docker/dev.dockerfile @@ -3,11 +3,14 @@ # Image with all cclyzer++ development tools, i.e., everything needed by # cclyzer++ developers to build and test cclyzer++. -# TODO(#12): Upgrade to Clang 15, LLVM 15 ARG UBUNTU_NAME=jammy ARG UBUNTU_VERSION=22.04 FROM ubuntu:$UBUNTU_VERSION as dev -# See NOTE[Clang+LLVM] in ci.yml +# See the documentation for supported versions. +# +# See NOTE[Clang+LLVM] in ci.yml. +# +# TODO(#12, #113): Upgrade to Clang 15, LLVM 15. ARG CLANG_VERSION=14 ARG LLVM_MAJOR_VERSION=14 # https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact @@ -47,7 +50,7 @@ RUN apt-get update && \ apt-get update && \ apt-get --yes install --no-install-recommends souffle RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \ - if [[ ${LLVM_VERSION} -lt 13 ]]; then \ + if [[ ${LLVM_MAJOR_VERSION} -lt 13 ]]; then \ echo "deb http://apt.llvm.org/${UBUNTU_NAME}/ llvm-toolchain-${UBUNTU_NAME} main" | tee /etc/apt/sources.list.d/llvm.list; \ else \ echo "deb http://apt.llvm.org/${UBUNTU_NAME}/ llvm-toolchain-${UBUNTU_NAME}-${LLVM_MAJOR_VERSION} main" | tee /etc/apt/sources.list.d/llvm.list; \ diff --git a/docker/dist.dockerfile b/docker/dist.dockerfile index b7743a3..d44e7aa 100644 --- a/docker/dist.dockerfile +++ b/docker/dist.dockerfile @@ -1,12 +1,34 @@ # See doc/docker.rst. -# TODO(#12): Upgrade to Ubuntu 22.04 (jammy), Clang 15, LLVM 15 -ARG UBUNTU_NAME=focal -ARG UBUNTU_VERSION=20.04 +ARG UBUNTU_NAME=jammy +ARG UBUNTU_VERSION=22.04 FROM ubuntu:$UBUNTU_VERSION as dist +# See the documentation for supported versions. +# +# See NOTE[Clang+LLVM] in ci.yml. +# +# TODO(#12, #113): Upgrade to Clang 15, LLVM 15. +ARG CLANG_VERSION=14 +ARG LLVM_MAJOR_VERSION=14 +# +# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG UBUNTU_NAME +ARG UBUNTU_VERSION SHELL ["/bin/bash", "-c", "-o", "pipefail"] -COPY ./build/cclyzer++*.deb /tmp/cclyzer++.deb ENV DEBIAN_FRONTEND=noninteractive + +COPY ./build/cclyzer++*.deb /tmp/cclyzer++.deb RUN apt-get update -qq && \ + apt install -y --no-install-recommends ca-certificates gnupg wget && \ + wget --no-verbose -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \ + if [[ ${LLVM_MAJOR_VERSION} -lt 13 ]]; then \ + echo "deb http://apt.llvm.org/${UBUNTU_NAME}/ llvm-toolchain-${UBUNTU_NAME} main" | tee /etc/apt/sources.list.d/llvm.list; \ + else \ + echo "deb http://apt.llvm.org/${UBUNTU_NAME}/ llvm-toolchain-${UBUNTU_NAME}-${LLVM_MAJOR_VERSION} main" | tee /etc/apt/sources.list.d/llvm.list; \ + fi && \ + apt-get update -qq && \ apt install -y /tmp/cclyzer++.deb && \ + apt-get remove -y gnupg wget && \ + apt-get -y autoremove && \ + rm -rf /var/lib/apt/lists/* && \ rm -f /tmp/cclyzer++.deb diff --git a/test/conftest.py b/test/conftest.py index e1d2ad9..8aa1e06 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -45,7 +45,7 @@ class ContextSensitivity(Enum): PARENT: Path = Path(realpath(__file__)).parent -BUILD: Path = PARENT.parent / "build" +BUILD: Path = Path(getenv("CCLYZER_BUILD_DIR", str(PARENT.parent / "build"))) PROGRAMS_PATH: Path = PARENT.parent / "test" / "c" # NOTE(ww): We don't use -Wall or -Werror here, since not all of our test