Index: test/DebugInfo/Inputs/split-dwarf-addr-object-relocation.cpp =================================================================== --- /dev/null +++ test/DebugInfo/Inputs/split-dwarf-addr-object-relocation.cpp @@ -0,0 +1,7 @@ +void f1(); +__attribute__((always_inline)) void f2() { + f1(); +} +void f3() { + f2(); +} Index: test/DebugInfo/Inputs/split-dwarf-multiple-cu1.cpp =================================================================== --- /dev/null +++ test/DebugInfo/Inputs/split-dwarf-multiple-cu1.cpp @@ -0,0 +1,2 @@ +extern int i; +int i; Index: test/DebugInfo/Inputs/split-dwarf-multiple-cu2.cpp =================================================================== --- /dev/null +++ test/DebugInfo/Inputs/split-dwarf-multiple-cu2.cpp @@ -0,0 +1,7 @@ +void f1(); +inline __attribute__((always_inline)) void f2() { + f1(); +} +void f3() { + f2(); +} Index: test/DebugInfo/llvm-symbolizer.test =================================================================== --- test/DebugInfo/llvm-symbolizer.test +++ test/DebugInfo/llvm-symbolizer.test @@ -20,8 +20,8 @@ RUN: echo "%p/Inputs/fission-ranges.elf-x86_64 0x720" >> %t.input RUN: echo "%p/Inputs/arange-overlap.elf-x86_64 0x714" >> %t.input RUN: cp %p/Inputs/split-dwarf-test.dwo %T -RUN: echo "%p/Inputs/split-dwarf-test 0x4005d4" >> %t.input -RUN: echo "%p/Inputs/split-dwarf-test 0x4005c4" >> %t.input +RUN: echo "%p/Inputs/split-dwarf-test 0x400504" >> %t.input +RUN: echo "%p/Inputs/split-dwarf-test 0x4004f0" >> %t.input RUN: echo "%p/Inputs/cross-cu-inlining.x86_64-macho.o 0x17" >> %t.input RUN: cp %p/Inputs/split-dwarf-multiple-cu.dwo %T RUN: echo "%p/Inputs/split-dwarf-multiple-cu.o 0x4" >> %t.input @@ -141,9 +141,9 @@ CHECK-NEXT: /tmp{{[/\\]}}cross-cu-inlining.c:11:0 CHECK: f2 -CHECK-NEXT: b.cpp:3:3 +CHECK-NEXT: split-dwarf-multiple-cu2.cpp:3:3 CHECK-NEXT: f3 -CHECK-NEXT: b.cpp:6:0 +CHECK-NEXT: split-dwarf-multiple-cu2.cpp:6:0 CHECK: f2 CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:3:3 Index: test/Other/lit-globbing.ll =================================================================== --- test/Other/lit-globbing.ll +++ test/Other/lit-globbing.ll @@ -1,28 +1,28 @@ -RUN: echo TA > %T/TA.txt -RUN: echo TB > %T/TB.txt -RUN: echo TAB > %T/TAB.txt - -RUN: echo %T/TA* | FileCheck -check-prefix=STAR %s -RUN: echo %T/'TA'* | FileCheck -check-prefix=STAR %s -RUN: echo %T/T'A'* | FileCheck -check-prefix=STAR %s - -RUN: echo %T/T?.txt | FileCheck -check-prefix=QUESTION %s -RUN: echo %T/'T'?.txt | FileCheck -check-prefix=QUESTION %s - -RUN: echo %T/T??.txt | FileCheck -check-prefix=QUESTION2 %s -RUN: echo %T/'T'??.txt | FileCheck -check-prefix=QUESTION2 %s - -RUN: echo 'T*' 'T?.txt' 'T??.txt' | FileCheck -check-prefix=QUOTEDARGS %s - -STAR-NOT: TB.txt -STAR: {{(TA.txt.*TAB.txt|TAB.txt.*TA.txt)}} - -QUESTION-NOT: TAB.txt -QUESTION: {{(TA.txt.*TB.txt|TB.txt.*TA.txt)}} - -QUESTION2-NOT: TA.txt -QUESTION2-NOT: TB.txt -QUESTION2: TAB.txt - -QUOTEDARGS-NOT: .txt -QUOTEDARGS: T* T?.txt T??.txt +RUN: echo XXA > %T/XXA.txt +RUN: echo XXB > %T/XXB.txt +RUN: echo XXAB > %T/XXAB.txt + +RUN: echo %T/XXA* | FileCheck -check-prefix=STAR %s +RUN: echo %T/'XXA'* | FileCheck -check-prefix=STAR %s +RUN: echo %T/XX'A'* | FileCheck -check-prefix=STAR %s + +RUN: echo %T/XX?.txt | FileCheck -check-prefix=QUESTION %s +RUN: echo %T/'XX'?.txt | FileCheck -check-prefix=QUESTION %s + +RUN: echo %T/XX??.txt | FileCheck -check-prefix=QUESTION2 %s +RUN: echo %T/'XX'??.txt | FileCheck -check-prefix=QUESTION2 %s + +RUN: echo 'XX*' 'XX?.txt' 'XX??.txt' | FileCheck -check-prefix=QUOTEDARGS %s + +STAR-NOT: XXB.txt +STAR: {{(XXA.txt.*XXAB.txt|XXAB.txt.*XXA.txt)}} + +QUESTION-NOT: XXAB.txt +QUESTION: {{(XXA.txt.*XXB.txt|XXB.txt.*XXA.txt)}} + +QUESTION2-NOT: XXA.txt +QUESTION2-NOT: XXB.txt +QUESTION2: XXAB.txt + +QUOTEDARGS-NOT: .txt +QUOTEDARGS: XX* XX?.txt XX??.txt Index: test/Unit/lit.cfg =================================================================== --- test/Unit/lit.cfg +++ test/Unit/lit.cfg @@ -39,9 +39,11 @@ config.environment[symbolizer] = os.environ[symbolizer] # Win32 seeks DLLs along %PATH%. -if sys.platform in ['win32', 'cygwin'] and os.path.isdir(config.shlibdir): - config.environment['PATH'] = os.path.pathsep.join(( - config.shlibdir, config.environment['PATH'])) +if sys.platform in ['win32', 'cygwin']: + shlibdir = getattr(config, 'shlibdir', None) + if shlibdir is not None and os.path.isdir(shlibdir): + config.environment['PATH'] = os.path.pathsep.join(( + config.shlibdir, config.environment['PATH'])) # Win32 may use %SYSTEMDRIVE% during file system shell operations, so propogate. if sys.platform == 'win32' and 'SYSTEMDRIVE' in os.environ: Index: utils/lit/lit/Test.py =================================================================== --- utils/lit/lit/Test.py +++ utils/lit/lit/Test.py @@ -172,7 +172,7 @@ return os.path.join(self.source_root, *components) def getExecPath(self, components): - return os.path.join(self.exec_root, *components) + return os.path.join(self.exec_root, "Output", *components) class Test: """Test - Information on a single test instance.""" @@ -226,6 +226,9 @@ def getFullName(self): return self.suite.config.name + ' :: ' + '/'.join(self.path_in_suite) + def getTestBaseName(self): + return self.path_in_suite[-1] + def getFilePath(self): if self.file_path: return self.file_path @@ -234,8 +237,11 @@ def getSourcePath(self): return self.suite.getSourcePath(self.path_in_suite) - def getExecPath(self): - return self.suite.getExecPath(self.path_in_suite) + def getTempFilePrefix(self): + return self.suite.getExecPath(self.path_in_suite) + ".tmp" + + def getTempFileDir(self): + return os.path.dirname(self.getTempFilePrefix()) def isExpectedToFail(self): """ Index: utils/lit/lit/TestRunner.py =================================================================== --- utils/lit/lit/TestRunner.py +++ utils/lit/lit/TestRunner.py @@ -690,37 +690,28 @@ finally: f.close() -def getTempPaths(test): - """Get the temporary location, this is always relative to the test suite - root, not test source root.""" - execpath = test.getExecPath() - execdir,execbase = os.path.split(execpath) - tmpDir = os.path.join(execdir, 'Output') - tmpBase = os.path.join(tmpDir, execbase) - return tmpDir, tmpBase - -def getDefaultSubstitutions(test, tmpDir, tmpBase, normalize_slashes=False): +def getDefaultSubstitutions(test, normalize_slashes=False): sourcepath = test.getSourcePath() sourcedir = os.path.dirname(sourcepath) + tmpDir = test.getTempFileDir() + tmpPrefix = test.getTempFilePrefix() + baseName = test.getTestBaseName() # Normalize slashes, if requested. if normalize_slashes: sourcepath = sourcepath.replace('\\', '/') sourcedir = sourcedir.replace('\\', '/') tmpDir = tmpDir.replace('\\', '/') - tmpBase = tmpBase.replace('\\', '/') # We use #_MARKER_# to hide %% while we do the other substitutions. substitutions = [] substitutions.extend([('%%', '#_MARKER_#')]) substitutions.extend(test.config.substitutions) - tmpName = tmpBase + '.tmp' - baseName = os.path.basename(tmpBase) substitutions.extend([('%s', sourcepath), ('%S', sourcedir), ('%p', sourcedir), ('%{pathsep}', os.pathsep), - ('%t', tmpName), + ('%t', tmpPrefix), ('%basename_t', baseName), ('%T', tmpDir), ('#_MARKER_#', '%')]) @@ -730,7 +721,7 @@ ('%/s', sourcepath.replace('\\', '/')), ('%/S', sourcedir.replace('\\', '/')), ('%/p', sourcedir.replace('\\', '/')), - ('%/t', tmpBase.replace('\\', '/') + '.tmp'), + ('%/t', tmpPrefix.replace('\\', '/')), ('%/T', tmpDir.replace('\\', '/')), ]) @@ -740,7 +731,7 @@ ('%:s', re.sub(r'^(.):', r'\1', sourcepath)), ('%:S', re.sub(r'^(.):', r'\1', sourcedir)), ('%:p', re.sub(r'^(.):', r'\1', sourcedir)), - ('%:t', re.sub(r'^(.):', r'\1', tmpBase) + '.tmp'), + ('%:t', re.sub(r'^(.):', r'\1', tmpPrefix)), ('%:T', re.sub(r'^(.):', r'\1', tmpDir)), ]) else: @@ -748,7 +739,7 @@ ('%:s', sourcepath), ('%:S', sourcedir), ('%:p', sourcedir), - ('%:t', tmpBase + '.tmp'), + ('%:t', tmpPrefix), ('%:T', tmpDir), ]) return substitutions @@ -1014,12 +1005,8 @@ return script - def _runShTest(test, litConfig, useExternalSh, script, tmpBase): - # Create the output directory if it does not already exist. - lit.util.mkdir_p(os.path.dirname(tmpBase)) - - execdir = os.path.dirname(test.getExecPath()) + execdir = os.path.dirname(test.getTempFileDir()) if useExternalSh: res = executeScript(test, litConfig, tmpBase, script, execdir) else: @@ -1063,10 +1050,8 @@ return script if litConfig.noExecute: return lit.Test.Result(Test.PASS) - - tmpDir, tmpBase = getTempPaths(test) substitutions = list(extra_substitutions) - substitutions += getDefaultSubstitutions(test, tmpDir, tmpBase, + substitutions += getDefaultSubstitutions(test, normalize_slashes=useExternalSh) script = applySubstitutions(script, substitutions) @@ -1075,7 +1060,8 @@ if hasattr(test.config, 'test_retry_attempts'): attempts += test.config.test_retry_attempts for i in range(attempts): - res = _runShTest(test, litConfig, useExternalSh, script, tmpBase) + res = _runShTest(test, litConfig, useExternalSh, script, + test.getTempFilePrefix()) if res.code != Test.FAIL: break # If we had to run the test more than once, count it as a flaky pass. These Index: utils/lit/lit/run.py =================================================================== --- utils/lit/lit/run.py +++ utils/lit/lit/run.py @@ -248,6 +248,28 @@ if not self.tests or jobs == 0: return + # Create fresh output directories for each test we're going to run. + # This guarantees that test runs will not remnants of previous test + # runs' output. + import time + start = time.time() + clean_paths = set() + for test in self.tests: + clean_paths.add(os.path.normpath(test.getTempFileDir())) + clean_paths = list(clean_paths) + clean_paths.sort(key=lambda x: len(x.split(os.sep))) + for base in clean_paths: + if os.path.exists(base): + if not os.path.islink(base) and os.path.isdir(base): + from shutil import rmtree + rmtree(base, True) + else: + os.unlink(os.path) + if not os.path.exists(base): + lit.util.mkdir_p(base) + end = time.time() + print("Cleanup took {} seconds".format(end - start)) + # Set up semaphores to limit parallelism of certain classes of tests. # For example, some ASan tests require lots of virtual memory and run # faster with less parallelism on OS X.