mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Deprecate string literals as (static) assert conditions (#15860)
* Deprecate string literals as assert conditions Fix Issue 14387 - Disallow string literals as assert conditions * Avoid running expression semantic, only deprecate literals Ignore enum strings. * Fix runnable test
This commit is contained in:
parent
7f74cb30db
commit
dea9e0e586
5 changed files with 55 additions and 1 deletions
18
changelog/dmd.assert-string.dd
Normal file
18
changelog/dmd.assert-string.dd
Normal file
|
@ -0,0 +1,18 @@
|
|||
A string literal as an assert condition is deprecated
|
||||
|
||||
Boolean evaluation of a string literal could happen unintentionally
|
||||
e.g. when an `assert(0, "message")` was meant and the `0` was missing.
|
||||
|
||||
```d
|
||||
assert("unexpected runtime condition");
|
||||
static assert("unhandled case for `", T, "`");
|
||||
```
|
||||
|
||||
The 2 asserts would silently always have no effect.
|
||||
Now these cases will be detected with deprecation messages.
|
||||
If the original behaviour was actually intended, use `expr !is null` instead:
|
||||
|
||||
```d
|
||||
assert("" !is null);
|
||||
static assert("" !is null);
|
||||
```
|
|
@ -7592,6 +7592,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
{
|
||||
printf("AssertExp::semantic('%s')\n", exp.toChars());
|
||||
}
|
||||
if (auto e = exp.e1.isStringExp())
|
||||
{
|
||||
// deprecated in 2.107
|
||||
deprecation(e.loc, "assert condition cannot be a string literal");
|
||||
deprecationSupplemental(e.loc, "If intentional, use `%s !is null` instead to preserve behaviour",
|
||||
e.toChars());
|
||||
}
|
||||
|
||||
const generateMsg = !exp.msg &&
|
||||
sc.needsCodegen() && // let ctfe interpreter handle the error message
|
||||
|
|
|
@ -93,6 +93,13 @@ private extern(C++) final class Semantic2Visitor : Visitor
|
|||
override void visit(StaticAssert sa)
|
||||
{
|
||||
//printf("StaticAssert::semantic2() %s\n", sa.toChars());
|
||||
if (const e = sa.exp.isStringExp())
|
||||
{
|
||||
// deprecated in 2.107
|
||||
deprecation(e.loc, "static assert condition cannot be a string literal");
|
||||
deprecationSupplemental(e.loc, "If intentional, use `%s !is null` instead to preserve behaviour",
|
||||
e.toChars());
|
||||
}
|
||||
auto sds = new ScopeDsymbol();
|
||||
sc = sc.push(sds);
|
||||
sc.tinst = null;
|
||||
|
|
22
compiler/test/fail_compilation/array_bool.d
Normal file
22
compiler/test/fail_compilation/array_bool.d
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
REQUIRED_ARGS: -de
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/array_bool.d(13): Deprecation: assert condition cannot be a string literal
|
||||
fail_compilation/array_bool.d(13): If intentional, use `"foo" !is null` instead to preserve behaviour
|
||||
fail_compilation/array_bool.d(14): Deprecation: static assert condition cannot be a string literal
|
||||
fail_compilation/array_bool.d(14): If intentional, use `"foo" !is null` instead to preserve behaviour
|
||||
---
|
||||
*/
|
||||
void main()
|
||||
{
|
||||
assert("foo");
|
||||
static assert("foo");
|
||||
|
||||
assert("foo".ptr); // OK
|
||||
static assert("foo".ptr); // OK
|
||||
|
||||
enum e = "bar";
|
||||
static assert(e); // OK
|
||||
assert(e); // OK
|
||||
}
|
|
@ -1087,7 +1087,7 @@ bool openDebugInfo(IDiaDataSource* source, IDiaSession* session, IDiaSymbol* glo
|
|||
{
|
||||
wchar[MAX_PATH] exepath;
|
||||
DWORD len = GetModuleFileNameW(null, exepath.ptr, MAX_PATH);
|
||||
len < MAX_PATH || assert("executable path too long");
|
||||
len < MAX_PATH || assert(false, "executable path too long");
|
||||
|
||||
HRESULT hr = CoInitialize(NULL);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue