diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index a4e3c7ecc035..80b5c9aa79b1 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -5956,6 +5956,30 @@ final class CParser(AST) : Parser!AST AST.Type t; + bool hasMinus; + if (token.value == TOK.min) + { + nextToken(); + // Only allow integer and float literals after minus. + switch (token.value) + { + case TOK.int32Literal: + case TOK.uns32Literal: + case TOK.int64Literal: + case TOK.uns64Literal: + case TOK.float32Literal: + case TOK.float64Literal: + case TOK.float80Literal: + case TOK.imaginary32Literal: + case TOK.imaginary64Literal: + case TOK.imaginary80Literal: + hasMinus = true; + break; + default: + continue; + } + } + Lswitch: switch (token.value) { @@ -5980,6 +6004,8 @@ final class CParser(AST) : Parser!AST * enum id = intvalue; */ AST.Expression e = new AST.IntegerExp(scanloc, intvalue, t); + if (hasMinus) + e = new AST.NegExp(scanloc, e); auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest); addSym(v); ++p; @@ -6003,6 +6029,8 @@ final class CParser(AST) : Parser!AST * enum id = floatvalue; */ AST.Expression e = new AST.RealExp(scanloc, floatvalue, t); + if (hasMinus) + e = new AST.NegExp(scanloc, e); auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest); addSym(v); ++p; diff --git a/compiler/test/compilable/imports/defines.c b/compiler/test/compilable/imports/defines.c index 6b0746f8ff96..420679a4fccb 100644 --- a/compiler/test/compilable/imports/defines.c +++ b/compiler/test/compilable/imports/defines.c @@ -55,3 +55,11 @@ int pr16199c() { return 8; } + +// https://issues.dlang.org/show_bug.cgi?id=24639 +#define NEGATIVE_I32 -1 +#define NEGATIVE_U32 -2U +#define NEGATIVE_I64 -3LL +#define NEGATIVE_U64 -4LLU +#define NEGATIVE_F32 -5.0f +#define NEGATIVE_F64 -6.0 diff --git a/compiler/test/compilable/testdefines.d b/compiler/test/compilable/testdefines.d index 060e962920a6..58eefb7256a3 100644 --- a/compiler/test/compilable/testdefines.d +++ b/compiler/test/compilable/testdefines.d @@ -25,3 +25,17 @@ static assert(pr16199_ice == 3); static assert(pr16199d() == 7); static assert(pr16199c() == 8); + +// https://issues.dlang.org/show_bug.cgi?id=24639 +static assert(NEGATIVE_I32 == -1); +static assert(NEGATIVE_U32 == cast(uint)-2); +static assert(NEGATIVE_I64 == -3); +static assert(NEGATIVE_U64 == cast(ulong)-4L); +static assert(NEGATIVE_F32 == -5f); +static assert(NEGATIVE_F64 == -6); +static assert(is(typeof(NEGATIVE_I32) == int)); +static assert(is(typeof(NEGATIVE_U32) == uint)); +static assert(is(typeof(NEGATIVE_I64) == long)); +static assert(is(typeof(NEGATIVE_U64) == ulong)); +static assert(is(typeof(NEGATIVE_F32) == float)); +static assert(is(typeof(NEGATIVE_F64) == double));