From d4bd9b25953685becc1b8f704e5355c897e40425 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Grang Date: Tue, 10 Sep 2019 15:23:58 -0700 Subject: [PATCH] Cherry-picked from commit 628e418df1a009e0d073545cbef3604350e7b808 Merge: 0e3399b b31f790 Author: David Tarditi Date: Thu Jan 24 16:52:25 2019 -0800 Merge branch 'master' into pre-rc8 Update Checked C clang compiler to latest LLVM sources, by merging the Checked C changes into recent LLVM sources. The LLVM sources are approximately at where RC1 for v8.0 was forked. Testing: - Passes all Checked C clang tests. - Passes all but 2 clang tests. Those are pre-existing failures in the LLVM sources that we're merging with. --- llvm/.gitmodules | 6 + llvm/CMakeLists.txt | 14 +- llvm/projects/checkedc-wrapper/CMakeLists.txt | 64 +++ llvm/projects/checkedc-wrapper/README.md | 31 ++ llvm/projects/checkedc-wrapper/checkedc | 1 + llvm/projects/checkedc-wrapper/lit.cfg | 434 ++++++++++++++++++ .../projects/checkedc-wrapper/lit.site.cfg.in | 35 ++ llvm/tools/msbuild/install.bat | 12 +- llvm/tools/msbuild/toolset-vs2017.targets | 3 + llvm/tools/msbuild/toolset-vs2017_xp.targets | 21 + llvm/tools/msbuild/uninstall.bat | 10 +- llvm/utils/lit/lit/TestingConfig.py | 1 + 12 files changed, 617 insertions(+), 15 deletions(-) create mode 100644 llvm/.gitmodules create mode 100644 llvm/projects/checkedc-wrapper/CMakeLists.txt create mode 100644 llvm/projects/checkedc-wrapper/README.md create mode 100644 llvm/projects/checkedc-wrapper/checkedc create mode 100644 llvm/projects/checkedc-wrapper/lit.cfg create mode 100644 llvm/projects/checkedc-wrapper/lit.site.cfg.in create mode 100644 llvm/tools/msbuild/toolset-vs2017.targets create mode 100644 llvm/tools/msbuild/toolset-vs2017_xp.targets diff --git a/llvm/.gitmodules b/llvm/.gitmodules new file mode 100644 index 00000000000000..9a26b104da206e --- /dev/null +++ b/llvm/.gitmodules @@ -0,0 +1,6 @@ +[submodule "tools/clang"] + path = tools/clang + url = https://github.com/Microsoft/checkedc-clang +[submodule "projects/checkedc-wrapper/checkedc"] + path = projects/checkedc-wrapper/checkedc + url = https://github.com/Microsoft/checkedc diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index b144be50f8431d..601c315f6d7aee 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -204,14 +204,14 @@ option(LLVM_APPEND_VC_REV set(PACKAGE_NAME LLVM) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") -set(PACKAGE_BUGREPORT "https://bugs.llvm.org/") +set(PACKAGE_BUGREPORT "https://github.com/Microsoft/checkedc-clang/issues") set(BUG_REPORT_URL "${PACKAGE_BUGREPORT}" CACHE STRING "Default URL where bug reports are to be submitted.") # Configure CPack. -set(CPACK_PACKAGE_INSTALL_DIRECTORY "LLVM") -set(CPACK_PACKAGE_VENDOR "LLVM") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "CheckedC-LLVM") +set(CPACK_PACKAGE_VENDOR "Microsoft") set(CPACK_PACKAGE_VERSION_MAJOR ${LLVM_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${LLVM_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${LLVM_VERSION_PATCH}) @@ -219,7 +219,7 @@ set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION}) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT") set(CPACK_NSIS_COMPRESSOR "/SOLID lzma \r\n SetCompressorDictSize 32") if(WIN32 AND NOT UNIX) - set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "LLVM") + set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "CheckedC-LLVM") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\nsis_logo.bmp") set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\nsis_icon.ico") set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\cmake\\\\nsis_icon.ico") @@ -456,6 +456,12 @@ else() set(LINK_POLLY_INTO_TOOLS OFF) endif() +if (EXISTS ${LLVM_MAIN_SRC_DIR}/projects/checkedc-wrapper/checkedc) + set(CHECKEDC_IN_TREE TRUE) +else() + set(CHECKEDC_IN_TREE FALSE) +endif() + # Define an option controlling whether we should build for 32-bit on 64-bit # platforms, where supported. if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 ) diff --git a/llvm/projects/checkedc-wrapper/CMakeLists.txt b/llvm/projects/checkedc-wrapper/CMakeLists.txt new file mode 100644 index 00000000000000..72fc0486deacc6 --- /dev/null +++ b/llvm/projects/checkedc-wrapper/CMakeLists.txt @@ -0,0 +1,64 @@ +# This script adds the Checked C tests to the LLVM tests infrastructure, +# provided that the Checked C repo exists as a subdirectory. + +# LLVM uses the CMake meta-build system to generate the build system. +# The build system includes targets for running tests. +# +# The script adds a new target for running Checked C tests. +# To do that, it sets up the information needed by the LIT tool. + +if(CHECKEDC_IN_TREE) + add_subdirectory(checkedc/include) + + set(CHECKEDC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + set(CHECKEDC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + + + if (CMAKE_CFG_INTDIR STREQUAL ".") + set(LLVM_BUILD_MODE ".") + else () + set(LLVM_BUILD_MODE "%(build_mode)s") + endif () + + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) + + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + + list(APPEND CHECKEDC_TEST_DEPS + clang clang-headers checkedc-headers + ) + + if(CLANG_ENABLE_STATIC_ANALYZER) + list(APPEND CLANG_TEST_DEPS + clang-check + ) + endif() + + set(CHECKEDC_TEST_PARAMS + checkedc_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + +if( NOT CLANG_BUILT_STANDALONE ) + list(APPEND CHECKEDC_TEST_DEPS + llvm-config + FileCheck count not + opt + ) +endif() + + add_custom_target(checkedc-test-depends DEPENDS ${CHECKEDC_TEST_DEPS}) + + add_lit_testsuite(check-checkedc "Running the Checked C regression tests" + ${CMAKE_CURRENT_BINARY_DIR} + #LIT ${LLVM_LIT} + PARAMS ${CHECKEDC_TEST_PARAMS} + DEPENDS ${CHECKEDC_TEST_DEPS} + ARGS ${CHECKEDC_TEST_EXTRA_ARGS} + ) + + set_target_properties(check-checkedc PROPERTIES FOLDER "Checked C tests") + +endif() diff --git a/llvm/projects/checkedc-wrapper/README.md b/llvm/projects/checkedc-wrapper/README.md new file mode 100644 index 00000000000000..a47038e6ff7289 --- /dev/null +++ b/llvm/projects/checkedc-wrapper/README.md @@ -0,0 +1,31 @@ +# Summary + +Checked C is a research project to extend C with +static and dynamic checking to detect or prevent +common programming errors. + +This directory contains LLVM-specific files for +testing the LLVM implementation of Checked C. +The files include build system files and LLVM +test infrastructure configuration files. + +Checked C is a separate project from LLVM. +The specification for Checked C and the tests +for Checked C reside in a separate repo on +Github. To use those tests, clone the +Checked C repo to this directory: + +git clone https://github.com/Microsoft/checkedc + +## Why this directory exists. + +You might wonder why these files were not +placed directly into the Checked C repo, +allowing us to elide this directory entirely. +The build and test infrastructure configuration +files are derived directly from existing LLVM files, +so they are subject the LLVM license and copyright +terms. The Checked C repo is subject to the MIT +conflicting licenses in the repo, just for a few files. + + diff --git a/llvm/projects/checkedc-wrapper/checkedc b/llvm/projects/checkedc-wrapper/checkedc new file mode 100644 index 00000000000000..eb8239e168002e --- /dev/null +++ b/llvm/projects/checkedc-wrapper/checkedc @@ -0,0 +1 @@ +Subproject commit bc45607280f8ca1c4fc3208f3409b34749c1f728 diff --git a/llvm/projects/checkedc-wrapper/lit.cfg b/llvm/projects/checkedc-wrapper/lit.cfg new file mode 100644 index 00000000000000..37f0b9ef80d6a0 --- /dev/null +++ b/llvm/projects/checkedc-wrapper/lit.cfg @@ -0,0 +1,434 @@ +# -*- Python -*- + +import os +import platform +import re +import subprocess +import tempfile + +import lit.formats +import lit.util + +# Configuration file for the 'lit' test runner. + +# name: The name of this test suite. +config.name = 'checkedc' + +# Tweak PATH for Win32 +if platform.system() == 'Windows': + # Seek sane tools in directories and set to $PATH. + path = getattr(config, 'lit_tools_dir', None) + path = lit_config.getToolsPath(path, + config.environment['PATH'], + ['cmp.exe', 'grep.exe', 'sed.exe']) + if path is not None: + path = os.path.pathsep.join((path, + config.environment['PATH'])) + config.environment['PATH'] = path + +# Choose between lit's internal shell pipeline runner and a real shell. If +# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. +use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") +if use_lit_shell: + # 0 is external, "" is default, and everything else is internal. + execute_external = (use_lit_shell == "0") +else: + # Otherwise we default to internal on Windows and external elsewhere, as + # bash on Windows is usually very slow. + execute_external = (not sys.platform in ['win32']) + +# testFormat: The test format to use to interpret tests. +# +# For now we require '&&' between commands, until they get globally killed and +# the test runner updated. +config.test_format = lit.formats.ShTest(execute_external) + +# suffixes: A list of file extensions to treat as test files. +config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap'] + +# excludes: A list of directories to exclude from the testsuite. The 'Inputs' +# subdirectories contain auxiliary inputs for various tests in their parent +# directories. +config.excludes = ['samples', 'spec', 'Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt'] + +# test_source_root: The root path where tests are located. +config.test_source_root = os.path.dirname(__file__) + +# test_exec_root: The root path where tests should be run. +checkedc_obj_root = getattr(config, 'checkedc_obj_root', None) +if checkedc_obj_root is not None: + config.test_exec_root = os.path.join(checkedc_obj_root) + +# Set llvm_{src,obj}_root for use by others. +config.llvm_src_root = getattr(config, 'llvm_src_root', None) +config.llvm_obj_root = getattr(config, 'llvm_obj_root', None) + +# Clear some environment variables that might affect Clang. +# +# This first set of vars are read by Clang, but shouldn't affect tests +# that aren't specifically looking for these features, or are required +# simply to run the tests at all. +# +# FIXME: Should we have a tool that enforces this? + +# safe_env_vars = ('TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD', +# 'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET', +# 'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS', +# 'VC80COMNTOOLS') +possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS', + 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH', + 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH', + 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH', + 'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING', + 'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX', + 'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS', + 'LIBCLANG_RESOURCE_USAGE', + 'LIBCLANG_CODE_COMPLETION_LOGGING'] +# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it. +if platform.system() != 'Windows': + possibly_dangerous_env_vars.append('INCLUDE') +for name in possibly_dangerous_env_vars: + if name in config.environment: + del config.environment[name] + +# Tweak the PATH to include the tools dir and the scripts dir. +if checkedc_obj_root is not None: + clang_tools_dir = getattr(config, 'clang_tools_dir', None) + if not clang_tools_dir: + lit_config.fatal('No Clang tools dir set!') + llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) + if not llvm_tools_dir: + lit_config.fatal('No LLVM tools dir set!') + path = os.path.pathsep.join(( + clang_tools_dir, llvm_tools_dir, config.environment['PATH'])) + config.environment['PATH'] = path + llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) + if not llvm_libs_dir: + lit_config.fatal('No LLVM libs dir set!') + path = os.path.pathsep.join((llvm_libs_dir, + config.environment.get('LD_LIBRARY_PATH',''))) + config.environment['LD_LIBRARY_PATH'] = path + +### + +# Discover the 'clang' and 'clangcc' to use. + +import os + +def inferClang(PATH): + # Determine which clang to use. + clang = os.getenv('CLANG') + + # If the user set clang in the environment, definitely use that and don't + # try to validate. + if clang: + return clang + + # Otherwise look in the path. + clang = lit.util.which('clang', PATH) + + if not clang: + lit_config.fatal("couldn't find 'clang' program, try setting " + "CLANG in your environment") + + return clang + +config.clang = inferClang(config.environment['PATH']).replace('\\', '/') +if not lit_config.quiet: + lit_config.note('using clang: %r' % config.clang) + +# Plugins (loadable modules) +# TODO: This should be supplied by Makefile or autoconf. +if sys.platform in ['win32', 'cygwin']: + has_plugins = (config.enable_shared == 1) +else: + has_plugins = True + +if has_plugins and config.llvm_plugin_ext: + config.available_features.add('plugins') + +config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) ) +config.substitutions.append( ('%pluginext', config.llvm_plugin_ext) ) +config.substitutions.append( ('%PATH%', config.environment['PATH']) ) + +# Note that when substituting %clang_cc1 also fill in the include directory of +# the builtin headers. Those are part of even a freestanding environment, but +# Clang relies on the driver to locate them. +def getClangBuiltinIncludeDir(clang): + # FIXME: Rather than just getting the version, we should have clang print + # out its resource dir here in an easy to scrape form. + cmd = subprocess.Popen([clang, '-print-file-name=include'], + stdout=subprocess.PIPE, + env=config.environment) + if not cmd.stdout: + lit_config.fatal("Couldn't find the include dir for Clang ('%s')" % clang) + dir = cmd.stdout.read().strip() + if sys.platform in ['win32'] and execute_external: + # Don't pass dosish path separator to msys bash.exe. + dir = dir.replace('\\', '/') + # Ensure the result is an ascii string, across Python2.5+ - Python3. + return str(dir.decode('ascii')) + +def makeItaniumABITriple(triple): + m = re.match(r'(\w+)-(\w+)-(\w+)', triple) + if not m: + lit_config.fatal("Could not turn '%s' into Itanium ABI triple" % triple) + if m.group(3).lower() != 'win32': + # All non-win32 triples use the Itanium ABI. + return triple + return m.group(1) + '-' + m.group(2) + '-mingw32' + +def makeMSABITriple(triple): + m = re.match(r'(\w+)-(\w+)-(\w+)', triple) + if not m: + lit_config.fatal("Could not turn '%s' into MS ABI triple" % triple) + isa = m.group(1).lower() + vendor = m.group(2).lower() + os = m.group(3).lower() + if os == 'win32': + # If the OS is win32, we're done. + return triple + if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa): + # For x86 ISAs, adjust the OS. + return isa + '-' + vendor + '-win32' + # -win32 is not supported for non-x86 targets; use a default. + return 'i686-pc-win32' + +config.substitutions.append( ('%clang_cc1', + '%s -cc1 -internal-isystem %s -nostdsysteminc' + % (config.clang, + getClangBuiltinIncludeDir(config.clang))) ) +config.substitutions.append( ('%clang_cpp', ' ' + config.clang + + ' --driver-mode=cpp ')) +config.substitutions.append( ('%clang_cl', ' ' + config.clang + + ' --driver-mode=cl ')) +config.substitutions.append( ('%clangxx', ' ' + config.clang + + ' --driver-mode=g++ ')) +config.substitutions.append( ('%clang', ' ' + config.clang + ' ') ) +config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') ) +config.substitutions.append( ('%itanium_abi_triple', makeItaniumABITriple(config.target_triple)) ) +config.substitutions.append( ('%ms_abi_triple', makeMSABITriple(config.target_triple)) ) + +# The host triple might not be set, at least if we're compiling clang from +# an already installed llvm. +if config.host_triple and config.host_triple != '@LLVM_HOST_TRIPLE@': + config.substitutions.append( ('%target_itanium_abi_host_triple', '--target=%s' % makeItaniumABITriple(config.host_triple)) ) +else: + config.substitutions.append( ('%target_itanium_abi_host_triple', '') ) + +# FIXME: Find nicer way to prohibit this. +config.substitutions.append( + (' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") ) +config.substitutions.append( + (' clang\+\+ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***""")) +config.substitutions.append( + (' clang-cc ', + """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") ) +config.substitutions.append( + (' clang -cc1 ', + """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") ) +config.substitutions.append( + (' %clang-cc1 ', + """*** invalid substitution, use '%clang_cc1'. ***""") ) +config.substitutions.append( + (' %clang-cpp ', + """*** invalid substitution, use '%clang_cpp'. ***""") ) +config.substitutions.append( + (' %clang-cl ', + """*** invalid substitution, use '%clang_cl'. ***""") ) + +# For each occurrence of a clang tool name as its own word, replace it +# with the full path to the build directory holding that tool. This +# ensures that we are testing the tools just built and not some random +# tools that might happen to be in the user's PATH. +tool_dirs = os.path.pathsep.join((clang_tools_dir, llvm_tools_dir)) + +# Regex assertions to reject neighbor hyphens/dots (seen in some tests). +# For example, don't match 'clang-check-' or '.clang-format'. +NoPreHyphenDot = r"(? + + diff --git a/llvm/tools/msbuild/toolset-vs2017_xp.targets b/llvm/tools/msbuild/toolset-vs2017_xp.targets new file mode 100644 index 00000000000000..3b6889020ce4dc --- /dev/null +++ b/llvm/tools/msbuild/toolset-vs2017_xp.targets @@ -0,0 +1,21 @@ + + + + v4.0 + NoSupportCodeAnalysisXP;$(BeforeClCompileTargets) + + + + + + + + + + CheckWindowsSDK71A;$(PrepareForBuildDependsOn) + + + + + + diff --git a/llvm/tools/msbuild/uninstall.bat b/llvm/tools/msbuild/uninstall.bat index 0c8852ec46dbab..f114021a66eb3b 100644 --- a/llvm/tools/msbuild/uninstall.bat +++ b/llvm/tools/msbuild/uninstall.bat @@ -17,15 +17,15 @@ IF EXIST "%VCTargets%\LLVM.Cpp.Common.targets" del "%VCTargets%\LLVM.Cpp.Common. ECHO Uninstalling x64 Platform Toolset SET PlatformToolsets=%VCTargets%\Platforms\x64\PlatformToolsets -IF EXIST "%PlatformToolsets%\llvm\Toolset.props" del "%PlatformToolsets%\llvm\Toolset.props" -IF EXIST "%PlatformToolsets%\llvm\Toolset.targets" del "%PlatformToolsets%\llvm\Toolset.targets" +IF EXIST "%PlatformToolsets%\CheckedC-llvm\Toolset.props" del "%PlatformToolsets%\CheckedC-llvm\Toolset.props" +IF EXIST "%PlatformToolsets%\CheckedC-llvm\Toolset.targets" del "%PlatformToolsets%\CheckedC-llvm\Toolset.targets" IF EXIST "%PlatformToolsets%\llvm" rd "%PlatformToolsets%\llvm" ECHO Uninstalling Win32 Platform Toolset SET PlatformToolsets=%VCTargets%\Platforms\Win32\PlatformToolsets -IF EXIST "%PlatformToolsets%\llvm\Toolset.props" del "%PlatformToolsets%\llvm\Toolset.props" -IF EXIST "%PlatformToolsets%\llvm\Toolset.targets" del "%PlatformToolsets%\llvm\Toolset.targets" -IF EXIST "%PlatformToolsets%\llvm" rd "%PlatformToolsets%\llvm" +IF EXIST "%PlatformToolsets%\CheckedC-llvm\Toolset.props" del "%PlatformToolsets%\CheckedC-llvm\Toolset.props" +IF EXIST "%PlatformToolsets%\CheckedC-llvm\Toolset.targets" del "%PlatformToolsets%\CheckedC-llvm\Toolset.targets" +IF EXIST "%PlatformToolsets%\CheckedC-llvm" rd "%PlatformToolsets%\CheckedC-llvm" ECHO Uninstalling C++ Settings UI IF EXIST "%VCTargets%\1033\llvm-general.xml" del "%VCTargets%\1033\llvm-general.xml" diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index 8060688116be7d..c0992fef103865 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -34,6 +34,7 @@ def fromdefaults(litConfig): pass_vars.append('INCLUDE') pass_vars.append('LIB') pass_vars.append('PATHEXT') + pass_vars.append('PROGRAMDATA') environment['PYTHONBUFFERED'] = '1' for var in pass_vars: