diff options
| author | Gauthier Harnisch <tyker1@outlook.com> | 2019-06-15 08:32:56 +0000 |
|---|---|---|
| committer | Gauthier Harnisch <tyker1@outlook.com> | 2019-06-15 08:32:56 +0000 |
| commit | 0bb4d46b2be5edd58621416de72e995cd6dd7ec4 (patch) | |
| tree | ccc668ec1d20d2bd9c70d87d7d9a0801c853a385 /clang/test | |
| parent | e1aa69f75574b88ac18fbe683af39226ee5ad288 (diff) | |
| download | bcm5719-llvm-0bb4d46b2be5edd58621416de72e995cd6dd7ec4.tar.gz bcm5719-llvm-0bb4d46b2be5edd58621416de72e995cd6dd7ec4.zip | |
[clang] perform semantic checking in constant context
Summary:
Since the addition of __builtin_is_constant_evaluated the result of an expression can change based on whether it is evaluated in constant context. a lot of semantic checking performs evaluations with out specifying context. which can lead to wrong diagnostics.
for example:
```
constexpr int i0 = (long long)__builtin_is_constant_evaluated() * (1ll << 33); //#1
constexpr int i1 = (long long)!__builtin_is_constant_evaluated() * (1ll << 33); //#2
```
before the patch, #2 was diagnosed incorrectly and #1 wasn't diagnosed.
after the patch #1 is diagnosed as it should and #2 isn't.
Changes:
- add a flag to Sema to passe in constant context mode.
- in SemaChecking.cpp calls to Expr::Evaluate* are now done in constant context when they should.
- in SemaChecking.cpp diagnostics for UB are not checked for in constant context because an error will be emitted by the constant evaluator.
- in SemaChecking.cpp diagnostics for construct that cannot appear in constant context are not checked for in constant context.
- in SemaChecking.cpp diagnostics on constant expression are always emitted because constant expression are always evaluated.
- semantic checking for initialization of constexpr variables is now done in constant context.
- adapt test that were depending on warning changes.
- add test.
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62009
llvm-svn: 363488
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/SemaCXX/attr-nonnull.cpp | 32 | ||||
| -rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx11.cpp | 9 |
2 files changed, 36 insertions, 5 deletions
diff --git a/clang/test/SemaCXX/attr-nonnull.cpp b/clang/test/SemaCXX/attr-nonnull.cpp index 8fce99759b6..764e8d84081 100644 --- a/clang/test/SemaCXX/attr-nonnull.cpp +++ b/clang/test/SemaCXX/attr-nonnull.cpp @@ -52,3 +52,35 @@ void test(const X& x) { (void)(x != 0); // expected-warning{{null passed}} } } + +namespace test5 { + +constexpr int c = 0; + +__attribute__((nonnull)) +constexpr int f1(const int*, const int*) { + return 0; +} +constexpr int i1 = f1(&c, &c); +constexpr int i12 = f1(&c, 0); //expected-error {{constant expression}} expected-note {{null passed}} + +constexpr int f2(const int*, const int*) { + return 0; +} +constexpr int i2 = f2(0, 0); + +__attribute__((nonnull(2))) +constexpr int f3(const int*, const int*) { + return 0; +} +constexpr int i3 = f3(&c, 0); //expected-error {{constant expression}} expected-note {{null passed}} +constexpr int i32 = f3(0, &c); + +__attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of bounds}} +constexpr int f4(const int*, const int*) { + return 0; +} +constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} expected-note {{null passed}} +constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} expected-note {{null passed}} + +}
\ No newline at end of file diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 46a77e1814d..2f3fe09bfb5 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -438,8 +438,8 @@ static_assert(MangleChars(U"constexpr!") == 1768383, ""); constexpr char c0 = "nought index"[0]; constexpr char c1 = "nice index"[10]; -constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}} -constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}} +constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} +constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-note {{cannot refer to element -1 of array of 15 elements}} constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}} constexpr const char *p = "test" + 2; @@ -547,7 +547,7 @@ constexpr int xs6 = p[3]; // expected-error {{constant expression}} expected-not constexpr int xs0 = p[-3]; // ok constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} -constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // expected-note {{array 'zs' declared here}} +constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; static_assert(zs[0][0][0][0] == 1, ""); static_assert(zs[1][1][1][1] == 16, ""); static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} @@ -557,8 +557,7 @@ static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1) == 11, ""); / static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, ""); constexpr int err_zs_1_2_0_0 = zs[1][2][0][0]; // \ expected-error {{constant expression}} \ -expected-note {{cannot access array element of pointer past the end}} \ -expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} +expected-note {{cannot access array element of pointer past the end}} constexpr int fail(const int &p) { return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}} |

