Skip to content

Commit 1310f58

Browse files
committed
[Fortran/gfortran] Add a simple not tool to the test suite
Add a tool very similar to LLVM's not utility which inverts the return code of a command. The major difference is that the utility is not dependent on LLVM's libraries and performs less error checking than LLVM's not. It does support the --crash option when the command is expected to crash. The gfortran tests have been updated to use this.
1 parent 5482cc3 commit 1310f58

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

Fortran/gfortran/CMakeLists.txt

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ function(gfortran_add_compile_test expect_error main others fflags ldflags)
445445
if (expect_error)
446446
# Since we don't check for any particular error, we expect "some" error.
447447
# In that case, the compiler's diagnostic output will be non-empty.
448-
llvm_test_verify(${TESTCMD} -s %S/${out})
448+
llvm_test_verify(%b/not ${DIFFPROG} %S/${relpath}/${EMPTY_FILE} %S/${out})
449449
else ()
450450
llvm_test_verify(${DIFFPROG} %S/${relpath}/${EMPTY_FILE} %S/${out})
451451
endif ()
@@ -658,22 +658,10 @@ get_filename_component(ISO_FORTRAN_C_HEADER_DIR
658658
# otherwise.
659659
set(DIFFPROG)
660660
if (WIN32)
661-
# Windows support has been disabled earlier anyway, but at some point, we
662-
# should find a way to check if a file is non-empty on windows.
663-
message(FATAL_ERROR "No way to check file size in Windows.")
664661
find_program(DIFFPROG
665662
NAMES fc.exe
666663
REQUIRED)
667664
else ()
668-
# FIXME: For the moment, check if a file is not empty, by using the test
669-
# command/shell built-in on *nix. But it is not clear that all systems will
670-
# have this. What we really need is to invert the result of DIFFPROG. LLVM has
671-
# a not utility that will do just this. But it needs LLVM's build directory
672-
# to be present unless it is installed on the system already. It is not clear
673-
# if we can depend on this.
674-
find_program(TESTCMD
675-
NAMES test
676-
REQUIRED)
677665
find_program(DIFFPROG
678666
NAMES diff cmp
679667
REQUIRED)

tools/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ else()
3939
add_executable(build-timeit-target ALIAS timeit-target)
4040
llvm_add_host_executable(build-timeit timeit timeit.c)
4141
endif()
42+
43+
add_executable(not ${CMAKE_CURRENT_SOURCE_DIR}/not.cpp)

tools/not.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===- not.cpp - The 'not' testing tool -----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// Usage:
9+
// not cmd
10+
// Will return true if cmd doesn't crash and returns false.
11+
// not --crash cmd
12+
// Will return true if cmd crashes (e.g. for testing crash reporting).
13+
14+
// This file is a stripped down version of not.cpp from llvm/utils. This does
15+
// not depend on any LLVM library.
16+
17+
#include <cstdlib>
18+
#include <iostream>
19+
#include <sstream>
20+
21+
#ifdef _WIN32
22+
#include <windows.h>
23+
#endif
24+
25+
int main(int argc, const char **argv) {
26+
bool expectCrash = false;
27+
28+
++argv;
29+
--argc;
30+
31+
if (argc > 0 && std::string(argv[0]) == "--crash") {
32+
++argv;
33+
--argc;
34+
expectCrash = true;
35+
36+
// Crash is expected, so disable crash report and symbolization to reduce
37+
// output and avoid potentially slow symbolization.
38+
#ifdef _WIN32
39+
SetEnvironmentVariableA("LLVM_DISABLE_CRASH_REPORT", "1");
40+
SetEnvironmentVariableA("LLVM_DISABLE_SYMBOLIZATION", "1");
41+
#else
42+
setenv("LLVM_DISABLE_CRASH_REPORT", "1", 0);
43+
setenv("LLVM_DISABLE_SYMBOLIZATION", "1", 0);
44+
#endif
45+
}
46+
47+
if (argc == 0)
48+
return 1;
49+
50+
std::stringstream ss;
51+
ss << argv[0];
52+
for (int i = 1; i < argc; ++i)
53+
ss << " " << argv[i];
54+
std::string cmd = ss.str();
55+
int result = system(cmd.c_str());
56+
57+
#ifdef _WIN32
58+
// Handle abort() in msvcrt -- It has exit code as 3. abort(), aka
59+
// unreachable, should be recognized as a crash. However, some binaries use
60+
// exit code 3 on non-crash failure paths, so only do this if we expect a
61+
// crash.
62+
if (expectCrash && result == 3)
63+
result = -3;
64+
#endif
65+
66+
if (result < 0) {
67+
if (expectCrash)
68+
return 0;
69+
return 1;
70+
}
71+
72+
if (expectCrash)
73+
return 1;
74+
75+
return result == 0;
76+
}

0 commit comments

Comments
 (0)