summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorGauthier Harnisch <tyker1@outlook.com>2019-06-15 08:32:56 +0000
committerGauthier Harnisch <tyker1@outlook.com>2019-06-15 08:32:56 +0000
commit0bb4d46b2be5edd58621416de72e995cd6dd7ec4 (patch)
treeccc668ec1d20d2bd9c70d87d7d9a0801c853a385 /clang/test
parente1aa69f75574b88ac18fbe683af39226ee5ad288 (diff)
downloadbcm5719-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.cpp32
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp9
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}}
OpenPOWER on IntegriCloud