diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2017-03-09 17:02:16 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2017-03-09 17:02:16 +0000 |
commit | eb8480377129675b6a1e9ae8e56bf4ca2dfb481b (patch) | |
tree | 41166439b5387b5de1583b52aa56e761ca6d5421 | |
parent | 9a110981fc8e0d28844afd76f655cf5cd1c72754 (diff) |
Reapply r297382: "[compiler-rt][builtins] Add __isOSVersionAtLeast()"
Looks like the problem was a case-insensitive include of dispatch/dispatch.h.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@297392 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/builtins/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/builtins/os_version_check.c | 115 | ||||
-rw-r--r-- | test/CMakeLists.txt | 6 | ||||
-rw-r--r-- | test/builtins/CMakeLists.txt | 15 | ||||
-rw-r--r-- | test/builtins/TestCases/Darwin/lit.local.cfg | 9 | ||||
-rw-r--r-- | test/builtins/TestCases/Darwin/os_version_check_test.c | 19 | ||||
-rw-r--r-- | test/builtins/lit.cfg | 20 | ||||
-rw-r--r-- | test/builtins/lit.site.cfg.in | 7 | ||||
-rw-r--r-- | test/lit.common.cfg | 1 |
9 files changed, 191 insertions, 2 deletions
diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index fc4384af2..ad9059c33 100644 --- a/lib/builtins/CMakeLists.txt +++ b/lib/builtins/CMakeLists.txt @@ -132,6 +132,7 @@ set(GENERIC_SOURCES negvdi2.c negvsi2.c negvti2.c + os_version_check.c paritydi2.c paritysi2.c parityti2.c diff --git a/lib/builtins/os_version_check.c b/lib/builtins/os_version_check.c new file mode 100644 index 000000000..eef113de2 --- /dev/null +++ b/lib/builtins/os_version_check.c @@ -0,0 +1,115 @@ +/* ===-- os_version_check.c - OS version checking -------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements the function __isOSVersionAtLeast, used by + * Objective-C's @available + * + * ===----------------------------------------------------------------------=== + */ + +#ifdef __APPLE__ + +#include <CoreFoundation/CoreFoundation.h> +#include <dispatch/dispatch.h> +#include <TargetConditionals.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* These three variables hold the host's OS version. */ +static int32_t GlobalMajor, GlobalMinor, GlobalSubminor; +static dispatch_once_t DispatchOnceCounter; + +/* Find and parse the SystemVersion.plist file. */ +static void parseSystemVersionPList(void *Unused) { + (void)Unused; + + char *PListPath = "/System/Library/CoreServices/SystemVersion.plist"; + +#if TARGET_OS_SIMULATOR + char *PListPathPrefix = getenv("IPHONE_SIMULATOR_ROOT"); + if (!PListPathPrefix) + return; + char FullPath[strlen(PListPathPrefix) + strlen(PListPath) + 1]; + strcpy(FullPath, PListPathPrefix); + strcat(FullPath, PListPath); + PListPath = FullPath; +#endif + FILE *PropertyList = fopen(PListPath, "r"); + if (!PropertyList) + return; + + /* Dynamically allocated stuff. */ + CFDictionaryRef PListRef = NULL; + CFDataRef FileContentsRef = NULL; + UInt8 *PListBuf = NULL; + + fseek(PropertyList, 0, SEEK_END); + long PListFileSize = ftell(PropertyList); + if (PListFileSize < 0) + goto Fail; + rewind(PropertyList); + + PListBuf = malloc((size_t)PListFileSize); + if (!PListBuf) + goto Fail; + + size_t NumRead = fread(PListBuf, 1, (size_t)PListFileSize, PropertyList); + if (NumRead != (size_t)PListFileSize) + goto Fail; + + /* Get the file buffer into CF's format. We pass in a null allocator here * + * because we free PListBuf ourselves */ + FileContentsRef = CFDataCreateWithBytesNoCopy( + NULL, PListBuf, (CFIndex)NumRead, kCFAllocatorNull); + if (!FileContentsRef) + goto Fail; + + if (&CFPropertyListCreateWithData) + PListRef = CFPropertyListCreateWithData( + NULL, FileContentsRef, kCFPropertyListImmutable, NULL, NULL); + else + PListRef = CFPropertyListCreateFromXMLData(NULL, FileContentsRef, + kCFPropertyListImmutable, NULL); + if (!PListRef) + goto Fail; + + CFTypeRef OpaqueValue = + CFDictionaryGetValue(PListRef, CFSTR("ProductVersion")); + if (!OpaqueValue || CFGetTypeID(OpaqueValue) != CFStringGetTypeID()) + goto Fail; + + char VersionStr[32]; + if (!CFStringGetCString((CFStringRef)OpaqueValue, VersionStr, + sizeof(VersionStr), kCFStringEncodingUTF8)) + goto Fail; + sscanf(VersionStr, "%d.%d.%d", &GlobalMajor, &GlobalMinor, &GlobalSubminor); + +Fail: + if (PListRef) + CFRelease(PListRef); + if (FileContentsRef) + CFRelease(FileContentsRef); + free(PListBuf); + fclose(PropertyList); +} + +int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) { + /* Populate the global version variables, if they haven't already. */ + dispatch_once_f(&DispatchOnceCounter, NULL, parseSystemVersionPList); + + if (Major < GlobalMajor) return 1; + if (Major > GlobalMajor) return 0; + if (Minor < GlobalMinor) return 1; + if (Minor > GlobalMinor) return 0; + return Subminor <= GlobalSubminor; +} + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9b9c515a3..addc57997 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,9 +5,8 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.common.configured.in ${CMAKE_CURRENT_BINARY_DIR}/lit.common.configured) -# BlocksRuntime and builtins testsuites are not yet ported to lit. +# BlocksRuntime (and most of builtins) testsuites are not yet ported to lit. # add_subdirectory(BlocksRuntime) -# add_subdirectory(builtins) set(SANITIZER_COMMON_LIT_TEST_DEPS) if(COMPILER_RT_STANDALONE_BUILD) @@ -39,6 +38,9 @@ endif() # Run sanitizer tests only if we're sure that clang would produce # working binaries. if(COMPILER_RT_CAN_EXECUTE_TESTS) + if(COMPILER_RT_BUILD_BUILTINS) + add_subdirectory(builtins) + endif() if(COMPILER_RT_HAS_ASAN) add_subdirectory(asan) endif() diff --git a/test/builtins/CMakeLists.txt b/test/builtins/CMakeLists.txt new file mode 100644 index 000000000..443e552f8 --- /dev/null +++ b/test/builtins/CMakeLists.txt @@ -0,0 +1,15 @@ +set(BUILTINS_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +set(BUILTINS_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} builtins) +set(BUILTINS_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/TestCases) + +# Test cases. +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg +) + +add_lit_testsuite(check-builtins "Running the Builtins tests" + ${BUILTINS_TESTSUITES} + DEPENDS ${BUILTINS_TEST_DEPS}) +set_target_properties(check-builtins PROPERTIES FOLDER "Compiler-RT Misc") diff --git a/test/builtins/TestCases/Darwin/lit.local.cfg b/test/builtins/TestCases/Darwin/lit.local.cfg new file mode 100644 index 000000000..a85dfcd24 --- /dev/null +++ b/test/builtins/TestCases/Darwin/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Darwin']: + config.unsupported = True diff --git a/test/builtins/TestCases/Darwin/os_version_check_test.c b/test/builtins/TestCases/Darwin/os_version_check_test.c new file mode 100644 index 000000000..2692cd37e --- /dev/null +++ b/test/builtins/TestCases/Darwin/os_version_check_test.c @@ -0,0 +1,19 @@ +// RUN: %clang %s -o %t -mmacosx-version-min=10.5 -framework CoreFoundation -DMAJOR=%macos_version_major -DMINOR=%macos_version_minor -DSUBMINOR=%macos_version_subminor +// RUN: %run %t + +int __isOSVersionAtLeast(int Major, int Minor, int Subminor); + +int main() { + if (!__isOSVersionAtLeast(MAJOR, MINOR, SUBMINOR)) + return 1; + if (__isOSVersionAtLeast(MAJOR, MINOR, SUBMINOR + 1)) + return 1; + if (SUBMINOR && __isOSVersionAtLeast(MAJOR + 1, MINOR, SUBMINOR - 1)) + return 1; + if (SUBMINOR && !__isOSVersionAtLeast(MAJOR, MINOR, SUBMINOR - 1)) + return 1; + if (MAJOR && !__isOSVersionAtLeast(MAJOR - 1, MINOR + 1, SUBMINOR)) + return 1; + + return 0; +} diff --git a/test/builtins/lit.cfg b/test/builtins/lit.cfg new file mode 100644 index 000000000..0044df7ba --- /dev/null +++ b/test/builtins/lit.cfg @@ -0,0 +1,20 @@ +# -*- Python -*- + +import os + +# Setup config name. +config.name = 'Builtins' + +# Setup source root. +config.test_source_root = os.path.dirname(__file__) + +# Test suffixes. +config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm'] + +# Define %clang and %clangxx substitutions to use in test RUN lines. +config.substitutions.append( ("%clang ", " " + config.clang + " ") ) + +if config.host_os == 'Darwin': + config.substitutions.append( ("%macos_version_major", str(config.darwin_osx_version[0])) ) + config.substitutions.append( ("%macos_version_minor", str(config.darwin_osx_version[1])) ) + config.substitutions.append( ("%macos_version_subminor", str(config.darwin_osx_version[2])) ) diff --git a/test/builtins/lit.site.cfg.in b/test/builtins/lit.site.cfg.in new file mode 100644 index 000000000..c7fe82f94 --- /dev/null +++ b/test/builtins/lit.site.cfg.in @@ -0,0 +1,7 @@ +@LIT_SITE_CFG_IN_HEADER@ + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@BUILTINS_LIT_SOURCE_DIR@/lit.cfg") diff --git a/test/lit.common.cfg b/test/lit.common.cfg index f0d7c0bff..bffdc4331 100644 --- a/test/lit.common.cfg +++ b/test/lit.common.cfg @@ -129,6 +129,7 @@ if config.host_os == 'Darwin': try: osx_version = subprocess.check_output(["sw_vers", "-productVersion"]) osx_version = tuple(int(x) for x in osx_version.split('.')) + config.darwin_osx_version = osx_version if osx_version >= (10, 11): config.available_features.add('osx-autointerception') config.available_features.add('osx-ld64-live_support') |