Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang][Interp] Implement while and do-while loops
Differential Revision: https://reviews.llvm.org/D135433
- Loading branch information
Showing
3 changed files
with
264 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify %s | ||
// RUN: %clang_cc1 -std=c++14 -verify=ref %s | ||
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected-cpp20 %s | ||
// RUN: %clang_cc1 -std=c++20 -verify=ref %s | ||
|
||
// ref-no-diagnostics | ||
// expected-no-diagnostics | ||
|
||
namespace WhileLoop { | ||
constexpr int f() { | ||
int i = 0; | ||
while(false) { | ||
i = i + 1; | ||
} | ||
return i; | ||
} | ||
static_assert(f() == 0, ""); | ||
|
||
|
||
constexpr int f2() { | ||
int i = 0; | ||
while(i != 5) { | ||
i = i + 1; | ||
} | ||
return i; | ||
} | ||
static_assert(f2() == 5, ""); | ||
|
||
constexpr int f3() { | ||
int i = 0; | ||
while(true) { | ||
i = i + 1; | ||
|
||
if (i == 5) | ||
break; | ||
} | ||
return i; | ||
} | ||
static_assert(f3() == 5, ""); | ||
|
||
constexpr int f4() { | ||
int i = 0; | ||
while(i != 5) { | ||
|
||
i = i + 1; | ||
continue; | ||
i = i - 1; | ||
} | ||
return i; | ||
} | ||
static_assert(f4() == 5, ""); | ||
|
||
|
||
constexpr int f5(bool b) { | ||
int i = 0; | ||
|
||
while(true) { | ||
if (!b) { | ||
if (i == 5) | ||
break; | ||
} | ||
|
||
if (b) { | ||
while (i != 10) { | ||
i = i + 1; | ||
if (i == 8) | ||
break; | ||
|
||
continue; | ||
} | ||
} | ||
|
||
if (b) | ||
break; | ||
|
||
i = i + 1; | ||
continue; | ||
} | ||
|
||
return i; | ||
} | ||
static_assert(f5(true) == 8, ""); | ||
static_assert(f5(false) == 5, ""); | ||
|
||
#if 0 | ||
/// FIXME: This is an infinite loop, which should | ||
/// be rejected. | ||
constexpr int f6() { | ||
while(true); | ||
} | ||
#endif | ||
}; | ||
|
||
namespace DoWhileLoop { | ||
|
||
constexpr int f() { | ||
int i = 0; | ||
do { | ||
i = i + 1; | ||
} while(false); | ||
return i; | ||
} | ||
static_assert(f() == 1, ""); | ||
|
||
constexpr int f2() { | ||
int i = 0; | ||
do { | ||
i = i + 1; | ||
} while(i != 5); | ||
return i; | ||
} | ||
static_assert(f2() == 5, ""); | ||
|
||
|
||
constexpr int f3() { | ||
int i = 0; | ||
do { | ||
i = i + 1; | ||
if (i == 5) | ||
break; | ||
} while(true); | ||
return i; | ||
} | ||
static_assert(f3() == 5, ""); | ||
|
||
constexpr int f4() { | ||
int i = 0; | ||
do { | ||
i = i + 1; | ||
continue; | ||
i = i - 1; | ||
} while(i != 5); | ||
return i; | ||
} | ||
static_assert(f4() == 5, ""); | ||
|
||
constexpr int f5(bool b) { | ||
int i = 0; | ||
|
||
do { | ||
if (!b) { | ||
if (i == 5) | ||
break; | ||
} | ||
|
||
if (b) { | ||
do { | ||
i = i + 1; | ||
if (i == 8) | ||
break; | ||
|
||
continue; | ||
} while (i != 10); | ||
} | ||
|
||
if (b) | ||
break; | ||
|
||
i = i + 1; | ||
continue; | ||
} while(true); | ||
|
||
return i; | ||
} | ||
static_assert(f5(true) == 8, ""); | ||
static_assert(f5(false) == 5, ""); | ||
|
||
/// FIXME: This should be accepted in C++20 but is currently being rejected | ||
/// because the variable declaration doesn't have an initializier. | ||
#if __cplusplus >= 202002L | ||
constexpr int f6() { | ||
int i; | ||
do { | ||
i = 5; | ||
break; | ||
} while (true); | ||
return i; | ||
} | ||
static_assert(f6() == 5, ""); // expected-cpp20-error {{not an integral constant}} | ||
#endif | ||
|
||
#if 0 | ||
/// FIXME: This is an infinite loop, which should | ||
/// be rejected. | ||
constexpr int f7() { | ||
while(true); | ||
} | ||
#endif | ||
}; |