Skip to content

Commit 0641e8d

Browse files
committed
Merge branch 'dev' into dev-fixes.
This brings dev-fixes up-to-date with dev in preparation for submitting a new PR to Microsoft.
2 parents ad94795 + eca4529 commit 0641e8d

File tree

88 files changed

+2304
-1780
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2304
-1780
lines changed

automation/UNIX/build-and-test.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ fi
1313
set -ue
1414
set -o pipefail
1515

16-
./setup-files.sh
17-
./run-cmake.sh
18-
./test-clang.sh
16+
if [ "$RUN_LOCAL" = "no" ]; then
17+
./setup-files.sh
18+
./run-cmake.sh
19+
./test-clang.sh
20+
fi
21+
1922
./test-lnt.sh
20-
./build-package.sh
23+
24+
if [ "$RUN_LOCAL" = "no" ]; then
25+
./build-package.sh
26+
fi

automation/UNIX/config-vars.sh

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,24 @@ if [ -z "$BUILD_CPU_COUNT" ]; then
131131
export BUILD_CPU_COUNT=$(($NPROC*3/4))
132132
fi
133133

134+
if [ -z "$RUN_LOCAL" ]; then
135+
export RUN_LOCAL="no"
136+
fi
137+
134138
# LLVM Nightly Tests are enabled when LNT is a non-empty
135139
# string.
136140
if [ -z "$LNT" ]; then
137141
# Make sure LNT variable is defined so that scripts that require all variables
138142
# to be defined do not break.
139143
export LNT=""
140144
export LNT_RESULTS_DIR=""
141-
export LN_SCRIPT=""
145+
export LNT_SCRIPT=""
142146
else
143147
export LNT_RESULTS_DIR="${BUILD_BINARIESDIRECTORY}/LNT-Results-${BUILDCONFIGURATION}-${BUILDOS}"
144-
# We assume that lnt is installed in /lnt-install on test machines.
145-
export LNT_SCRIPT=/lnt-install/sandbox/bin/lnt
148+
if [ "$RUN_LOCAL" = "no" ]; then
149+
# We assume that lnt is installed in /lnt-install on test machines.
150+
export LNT_SCRIPT=/lnt-install/sandbox/bin/lnt
151+
fi
146152
fi
147153

148154
if [ "$CHECKEDC_CONFIG_STATUS" == "passed" ]; then
@@ -156,6 +162,7 @@ if [ "$CHECKEDC_CONFIG_STATUS" == "passed" ]; then
156162
echo " SKIP_CHECKEDC_TESTS: $SKIP_CHECKEDC_TESTS"
157163
echo " LNT: $LNT"
158164
echo " LNT_SCRIPT: $LNT_SCRIPT"
165+
echo " RUN_LOCAL: $RUN_LOCAL"
159166
echo
160167
echo " Directories:"
161168
echo " BUILD_SOURCESDIRECTORY: $BUILD_SOURCESDIRECTORY"

automation/UNIX/run-lnt-local.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/bash
2+
3+
# This script can be used to run LNT tests locally on a user's Linux machine.
4+
# For detailed setup instructions see
5+
# https://github.com/Microsoft/checkedc-llvm-test-suite/blob/master/README.md
6+
7+
usage() {
8+
echo "Usage: SRC_DIR=</path/to/llvm/src> BUILD_DIR=</path/to/llvm/build> $0"
9+
echo "Optional flags: TEST_TARGET=\"X86_64;ARM\" LNT_BIN=</path/to/lnt>"
10+
exit 1
11+
}
12+
13+
CURDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
14+
15+
if [ -z "$SRC_DIR" ]; then
16+
echo "Specify SRC_DIR as the dir containing LLVM sources."
17+
usage
18+
fi
19+
20+
if [ -z "$BUILD_DIR" ]; then
21+
echo "Specify BUILD_DIR as the dir containing LLVM build."
22+
usage
23+
fi
24+
25+
if [ -z "$TEST_TARGET" ]; then
26+
TEST_TARGET="X86_64;ARM"
27+
fi
28+
29+
if [ -z "$LNT_BIN" ]; then
30+
LNT_BIN=~/mysandbox/bin/lnt
31+
fi
32+
33+
rm -rf $BUILD_DIR/LNT-Results-Release-Linux $BUILD_DIR/LLVM-Release-Linux.obj
34+
ln -s $BUILD_DIR/llvm $BUILD_DIR/LLVM-Release-Linux.obj
35+
36+
if [ ! -d $SRC_DIR/llvm-test-suite ]; then
37+
echo "Checking out llvm-test-suite at $SRC_DIR/llvm-test-suite."
38+
cd $SRC_DIR
39+
git clone https://github.com/microsoft/checkedc-llvm-test-suite.git llvm-test-suite
40+
fi
41+
42+
cd $CURDIR
43+
export PATH=$BUILD_DIR/llvm/bin:$PATH
44+
45+
# Invoke lnt.
46+
BUILDCONFIGURATION=Release \
47+
BUILD_BINARIESDIRECTORY=$BUILD_DIR \
48+
BUILD_SOURCESDIRECTORY=$SRC_DIR \
49+
LNT_SCRIPT=$LNT_BIN \
50+
TEST_TARGET_ARCH=$TEST_TARGET \
51+
TEST_SUITE=CheckedC_clang \
52+
LNT=yes \
53+
RUN_LOCAL=yes \
54+
./build-and-test.sh

docs/checkedc/CheckedCConvert.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Checked-C-Convert
2+
3+
4+
This is a clang tool that tries to automatically convert `C` code to include `Checked
5+
C` types.
6+
7+
The tool is available under: `tools/checked-c-convert`
8+
9+
## Redesigning and new features
10+
11+
Corresponding pull request: [Porting Tool Updates](https://github.com/microsoft/checkedc-clang/pull/642)
12+
13+
In this pull request, we tried to faithfully implement the highlevel idea as described in the paper (Section 5.3 of [https://www.microsoft.com/en-us/research/uploads/prod/2019/05/checkedc-post2019.pdf](https://www.microsoft.com/en-us/research/uploads/prod/2019/05/checkedc-post2019.pdf))
14+
15+
If you see the Section 5.3 of the paper, there depending on how a parameter to a function is **used** by the callers and **used** inside the callee, we use `itype`s or casting. To do this, we need to have two sets of constraint variables for each of the function parameters i.e., one for the calleers (i.e., as seen outside the function) and one for the function body. Once we solve the constraints we can assign `itype` or casts. Similarly for return types.
16+
17+
However, our old implementation had inconsistencies in inferring checked types of the function parameters and returns. Specifically, when a function do not have a corresponding declaration e.g., `static` methods,
18+
19+
We changed this so that irrespective of whether a function has a explicit declaration or not we always maintain two sets of constraint variables for parameters and returns.
20+
21+
### Function Subtyping
22+
We introduced the support for `_Nt_array_ptrs`, this resulted in function subtyping issues as discussed in detail in: [https://gist.github.com/Machiry/962bf8c24117bc5f56a31598e6782100](https://gist.github.com/Machiry/962bf8c24117bc5f56a31598e6782100)
23+
We implemented support for this.
24+
25+
### Performance Improvements
26+
27+
We made performance imporvements to the tool. This is mainly because of a single line change (Thanks to @rchyena) in `ConstraintVariables.cpp`:
28+
from:
29+
```
30+
214: auto env = CS.getVariables();
31+
```
32+
to
33+
```
34+
214: auto &env = CS.getVariables();
35+
```
36+
#### Numbers for Icecast :
37+
**New**
38+
```
39+
real 3m51.869s
40+
user 3m50.132s
41+
sys 0m0.804s
42+
```
43+
**Old**
44+
```
45+
real 6m9.581s
46+
user 6m0.688s
47+
sys 0m8.004s
48+
```
49+
In general the current version of the tool is sufficiently fast, for `libarchive` (~170K lines) it took ~10min.
50+

docs/checkedc/Testing.md

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
11
# Testing the Checked C version of LLVM/clang
22

33
LLVM/clang have two kinds of tests: developer regression tests and extended
4-
tests. Developer regression tests are meant to be run by developers before any
5-
check-in and are quick to run. Extended tests are run as part of continuous
4+
tests. Developer regression tests are meant to be run by developers before any
5+
check-in and are quick to run. Extended tests are run as part of continuous
66
integration testing or for changes that require extensive testing.
77

88
## Developer regression tests
99

10-
We have created a new set of developer regression tests for the Checked C extension.
11-
We have added a new target to the build system for running the test suite: check-checkedc.
12-
The Checked C version of clang/LLVM should pass the existing clang and LLVM
13-
regression tests and the Checked C-specific regression tests. There should
14-
be no unexpected test failures. A developer should confirm this before committing a change.
10+
We have created a new set of developer regression tests for the Checked C
11+
extension. We have added a new target to the build system for running the test
12+
suite: check-checkedc. The Checked C version of clang/LLVM should pass the
13+
existing clang and LLVM regression tests and the Checked C-specific regression
14+
tests. There should be no unexpected test failures. A developer should confirm
15+
this before committing a change.
1516

16-
When testing a change, the testing should be sufficient for the type of change. For changes
17-
to parsing and typechecking, it is usually sufficient to pass the Checked C and clang tests.
17+
When testing a change, the testing should be sufficient for the type of change.
18+
For changes to parsing and typechecking, it is usually sufficient to pass the
19+
Checked C and clang tests.
1820

1921
## Running developer regressions tests
2022

2123
### From Visual Studio
22-
Load the solution and the open it using the Solution explorer (View->Solution Explorer). To run tests, you can right click and build the following targets:
24+
Load the solution and the open it using the Solution explorer (View->Solution
25+
Explorer). To run tests, you can right click and build the following targets:
2326

2427
- Checked C tests: go to _CheckedC tests->check-checkedc_
2528
- clang tests: go to _Clang tests->check-clang_
2629
- All LLVM and clang tests: select the check-all solution (at the top level)
2730

2831
### From a command shell using msbuild
29-
Set up the build system and then change to your new object directory. Use the following commands to run tests:
32+
Set up the build system and then change to your new object directory. Use the
33+
following commands to run tests:
3034

3135
- Checked C tests: `msbuild projects\checkedc-wrapper\check-checkedc.vcxproj /p:CL_MPCount=3 /m`
3236
- Clang tests: `msbuild tools\clang\test\check-clang.vcxproj /p:CL_MPCount=3 /m`
@@ -36,37 +40,81 @@ Set up the build system and then change to your new object directory. Use the f
3640
In your build directory,
3741

3842
- Checked C tests: `make -j nnn check-checkedc`
43+
- Checked C tests (for ARM target): `make -j nnn check-checkedc-arm`
3944
- clang tests: `make -j nnn check-clang`
4045
- All tests: `make -j nnn check-all`
4146

4247
where `nnn` is replaced by the number of CPU cores that your computer has.
4348

49+
Note: If you use CMake with ninja, then you can simply replace `make -j nnn` in
50+
the above commands with `ninja`. For example:
51+
52+
`ninja check-checkedc`
53+
4454
### From a command shell using the testing harness
4555
You can use the testing harness to run individual tests or sets of tests.
4656
These directions are adapted from http://llvm.org/docs/TestingGuide.html#id11.
47-
The clang-specific documentation on running tests appears to be out-of-date, so don't try to follow those directions.
57+
The clang-specific documentation on running tests appears to be out-of-date, so
58+
don't try to follow those directions.
59+
60+
- The build creates a llvm-lit.py script that you can use to run regression
61+
tests by hand. It is placed in the same directory as your newly built clang
62+
executable.
63+
64+
On Windows, the clang executable resides in:
65+
`<BUILD_DIR>\llvm\Debug\bin` for Debug builds
66+
`<BUILD_DIR>\llvm\Release\bin` for Release builds
67+
68+
On Linux, the clang executable resides in:
69+
`<BUILD_DIR>\llvm\bin`
70+
71+
- You can point the llvm-lit script at a directory to run all tests or an
72+
individual test. For example:
73+
74+
`llvm-lit <BUILD_DIR>\llvm\tools\clang\test`
75+
76+
### Running lit tests for ARM
77+
By default, the lit tests are built and run for the native X86 target. But you
78+
can also build and run them for other targets. Currently, we support lit
79+
testing for ARM. Here is how you enable ARM lit testing:
80+
81+
- Configure the Checked C compiler
82+
Specify these two CMake options when configuring the compiler during the
83+
build step:
84+
85+
`-DCHECKEDC_ARM_SYSROOT=<sysroot>` Specify the path to the top of an ARM
86+
sysroot which contains the ARM-specific headers and runtime libs.
87+
88+
`-DCHECKEDC_ARM_RUNUNDER=<device>` Specify the device to run the ARM lit
89+
tests on. For example, specify this as `qemu-arm` in order to run the tests on
90+
the ARM QEMU.
91+
92+
NOTE: If you want to run the tests on the QEMU, make sure that the QEMU is
93+
installed on the host machine.
4894

49-
- The build creates a llvm-lit.py script that you can use to run regression tests by hand.
50-
It is placed in the same directory as your newly built clang executable. Those are placed in {your build directory}\debug\bin.
95+
- Run lit for ARM
96+
Once you have built the Checked C compiler, this is how you would invoke lit
97+
for ARM testing:
5198

52-
- You can point the llvm-lit script at a directory to run all tests or an individual test. For example:
99+
`llvm-lit <SRC_DIR>\llvm\projects\checkedc-wrapper\checkedc\tests -DCHECKEDC_TARGET=ARM`
53100

54-
llvm-lit d:\autobahn1\llvm\tools\clang\test
101+
NOTE: LIT testing for ARM is only supported for tests under the directory
102+
`<SRC_DIR>\llvm\projects\checkedc-wrapper\checkedc\tests`.
55103

56104
### Unexpected test failures and line endings
57105

58106
If you see unexpected test failures when working on Windows using unchanged
59107
versions of the Checked C LLVM/clang repos, you should first check that you
60108
have set your line end handling for Git properly, particularly if you see a
61-
lot of failures. LLVM and clang have some tests that depend on line endings.
109+
lot of failures. LLVM and clang have some tests that depend on line endings.
62110
Those tests assume that all lines end with line feeds (the Unix line ending
63111
convention).
64112

65113
The LLVM/clang project uses Subversion for source code control, which does not
66-
alter line endings. We are using Git for source code control, which may alter
67-
line endings on Windows, depending on how you have configured Git. Git may
114+
alter line endings. We are using Git for source code control, which may alter
115+
line endings on Windows, depending on how you have configured Git. Git may
68116
alter text line endings to be carriage return/line feed (the Windows line
69-
ending convention). It is important to ensure that Git does not do this for
117+
ending convention). It is important to ensure that Git does not do this for
70118
your LLVM/clang repositories.
71119

72120
The configuration setting `core.autocrlf` should to be set to `false`. If you
@@ -75,11 +123,12 @@ it will be set to `false`.
75123

76124
## Extended testing
77125

78-
The extended testing for LLVM/clang is somewhat complicated to set up. It
79-
is oriented toward automated testing using servers and has the set-up complexity
80-
that comes with that. For the Checked C implementation, there are two kinds
81-
of extended testing that we do: testing that benchmarks that have been converted
82-
to Checked C work and testing that the Checked C implementation has not broken existing functionality.
126+
The extended testing for LLVM/clang is somewhat complicated to set up. It is
127+
oriented toward automated testing using servers and has the set-up complexity
128+
that comes with that. For the Checked C implementation, there are two kinds of
129+
extended testing that we do: testing that benchmarks that have been converted
130+
to Checked C work and testing that the Checked C implementation has not broken
131+
existing functionality.
83132

84133
To run benchmarks, clone the
85134
[Checked C LLVM test suite repo](https://github.com/microsoft/checkedc-llvm-test-suite)
@@ -91,16 +140,17 @@ check out the `original` branch of the
91140
and then follow the directions in the
92141
[README.md file](https://github.com/Microsoft/checkedc-llvm-test-suite/blob/master/README.md).
93142
Note that the `original` branch contains tests as well as benchmarks.
94-
It is much larger than the `master` branch. It will use more than 2 GBytes of disk space
143+
It is much larger than the `master` branch. It will use more than 2 GBytes of disk space
95144
and the testing will take much longer to run.
96145

97146

98147
## Gotchas
99148

100-
Windows x86 will cause issues if executables have "install", "setup", or "update" in
101-
their filename. It will assume the executable is an installer, and require that the user has
102-
elevated privileges to run the program. Usually inside visual studio this manifests itself
103-
as "WinError 740". There is more documentation on the heuristics used here:
149+
Windows x86 will cause issues if executables have "install", "setup", or
150+
"update" in their filename. It will assume the executable is an installer, and
151+
require that the user has elevated privileges to run the program. Usually
152+
inside visual studio this manifests itself as "WinError 740". There is more
153+
documentation on the heuristics used here:
104154
https://msdn.microsoft.com/en-us/enus/library/aa905330.aspx
105155

106156
We originally diagnosed this issue thanks to this stackoverflow post:

include/clang/AST/ASTContext.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,22 @@ class ASTContext : public RefCountedBase<ASTContext> {
279279
llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
280280
MaterializedTemporaryValues;
281281

282+
/// Mapping from (generic record decl, type arguments) pairs to instantiated record decls.
283+
/// e.g. (List, int) -> List<int>
284+
/// This keeps tracks of all type applications both so we can preserve the uniqueness invariant
285+
/// for decls and types, and also so we can typecheck complex recursive applications.
286+
llvm::DenseMap<std::pair<const RecordDecl *, ArrayRef<const Type *> >, RecordDecl *>
287+
CachedTypeApps;
288+
289+
/// Mapping from RecordDecls to list of delayed type applications.
290+
/// The key is a declaration or definition of the generic RecordDecl, and the
291+
/// corresponding values all have the given RecordDecl as base.
292+
/// e.g. List<T> -> [List<int>, List<List<char>>, List<char>, ...]
293+
/// Foo<T> -> [Foo<Foo<int>>, Foo<char>, ...]
294+
/// A delayed type application is represented as a RecordDecl for which RecordDecl::isInstantiated()
295+
/// returns 'true'. The parameters in a type application can be retrieved via RecordDecl::typeParams().
296+
llvm::DenseMap<const RecordDecl *, llvm::SmallVector<RecordDecl *, 4> > DelayedTypeApps;
297+
282298
/// Representation of a "canonical" template template parameter that
283299
/// is used in canonical template names.
284300
class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
@@ -3074,6 +3090,34 @@ class ASTContext : public RefCountedBase<ASTContext> {
30743090
};
30753091

30763092
llvm::StringMap<SectionInfo> SectionInfos;
3093+
3094+
public:
3095+
//===--------------------------------------------------------------------===//
3096+
// Checked C: type applications
3097+
//===--------------------------------------------------------------------===//
3098+
3099+
/// Get the result of the type application 'Base<TypeArgs>', if it's been already cached.
3100+
/// If it's not cached, return 'nullptr'.
3101+
RecordDecl *getCachedTypeApp(const RecordDecl *Base, ArrayRef<const Type *> TypeArgs);
3102+
3103+
/// Return all type applications that have the given generic decl as base.
3104+
/// This is currently slow since it iterates over all cached type applications.
3105+
/// TODO: improve its efficiency. See issues/644.
3106+
std::vector<const RecordDecl *> getTypeAppsWithBase(const RecordDecl *Base);
3107+
3108+
/// Add the instantiated record type 'Inst' as the result of the type application 'Base<TypeArgs>'.
3109+
/// Cached applications shouldn't be overwritten, so this should be called at most once per key.
3110+
void addCachedTypeApp(const RecordDecl *Base, ArrayRef<const Type *> TypeArgs, RecordDecl *Inst);
3111+
3112+
/// Get the list of type applications that have 'Base' as their base RecordDecl.
3113+
ArrayRef<RecordDecl *> getDelayedTypeApps(RecordDecl *Base);
3114+
3115+
/// Add TypeApp to the cache using TypeApp's base field as the key.
3116+
void addDelayedTypeApp(RecordDecl *TypeApp);
3117+
3118+
/// Remove all type applications that have 'Base' as their base RecordDecl.
3119+
/// Return 'true' if the removed key was in the cache, and 'false' otherwise.
3120+
bool removeDelayedTypeApps(RecordDecl *Base);
30773121
};
30783122

30793123
/// Utility function for constructing a nullary selector.

0 commit comments

Comments
 (0)