From b237d0329c823950e6f486503b1421264abd37ba Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 10 Jan 2025 23:35:51 +0100 Subject: [PATCH 1/6] Fix ambiguous type deduction around hex strings (#20679) --- compiler/src/dmd/dcast.d | 6 ++++++ compiler/test/runnable/literal.d | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index ce51c28f6e..29f5dd23b6 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -703,6 +703,12 @@ MATCH implicitConvTo(Expression e, Type t) if (!tn.isConst() && !tn.isImmutable()) return MATCH.nomatch; m = MATCH.constant; + + // After converting e.g. ubyte[] to const(ubyte)[], don't change + // to MATCH.convert, return MATCH.constant + // https://github.com/dlang/dmd/issues/20635 + if (e.type.ty == t.ty && e.type.nextOf().ty == tn.ty) + return m; } if (e.type != t && e.hexString && tn.isintegral && (tn.size == e.sz || (!e.committed && (e.len % tn.size) == 0))) { diff --git a/compiler/test/runnable/literal.d b/compiler/test/runnable/literal.d index 3cc7e51197..c78f4776aa 100644 --- a/compiler/test/runnable/literal.d +++ b/compiler/test/runnable/literal.d @@ -277,8 +277,16 @@ void testHexstring() static immutable ulong[] z0 = cast(immutable ulong[]) x"1111 1111 1111 1111 0000 000F 0000 0000"; static immutable ulong[] z1 = [0x1111_1111_1111_1111, 0x0000_000E_0000_0000]; static assert(z0 !is z1); + + // https://github.com/dlang/dmd/issues/20635 + f20635(cast(ubyte[]) x"00"); + f20635(cast(const ubyte[]) x"00"); + f20635(cast(immutable ubyte[]) x"00"); } +void f20635(const ubyte[] value){} +void f20635(const string value){} + /***************************************************/ int main() From ac9e8a5a700346ef0479a24e5bd5544395b3965c Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 17 Jan 2025 01:50:17 +0100 Subject: [PATCH 2/6] Fix bypassing nothrow in debug statements (#20720) * Fix bypassing nothrow in debug statements * Fix debug walking null statements --- compiler/src/dmd/expressionsem.d | 5 ----- compiler/src/dmd/statementsem.d | 16 +++++++++++++--- ...{test16492.d => debug_statement_attributes.d} | 14 ++++++++++++++ compiler/test/compilable/test24017.d | 11 ----------- 4 files changed, 27 insertions(+), 19 deletions(-) rename compiler/test/compilable/{test16492.d => debug_statement_attributes.d} (73%) delete mode 100644 compiler/test/compilable/test24017.d diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 6ebb20a56a..ee8eb36465 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -1363,11 +1363,6 @@ private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 auto arguments = new Expressions(1); (*arguments)[0] = eleft; e = new CallExp(loc, e, arguments); - - // https://issues.dlang.org/show_bug.cgi?id=24017 - if (sc.flags & SCOPE.debug_) - e.isCallExp().inDebugStatement = true; - e = e.expressionSemantic(sc); return e; } diff --git a/compiler/src/dmd/statementsem.d b/compiler/src/dmd/statementsem.d index 0390892efe..502a4c2bd6 100644 --- a/compiler/src/dmd/statementsem.d +++ b/compiler/src/dmd/statementsem.d @@ -134,7 +134,16 @@ private Expression checkAssignmentAsCondition(Expression e, Scope* sc) return e; } -// Performs semantic analysis in Statement AST nodes +/** + * Performs semantic analysis in Statement AST nodes + * + * Params: + * s = statement to perform semantic analysis on + * sc = scope in which statement resides + * + * Returns: statement `s` after semantic analysis. + * Can be `null`, for example with `pragma(msg, "")` + */ Statement statementSemantic(Statement s, Scope* sc) { import dmd.compiler; @@ -3461,6 +3470,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) sc = sc.push(); sc.flags |= SCOPE.debug_; ds.statement = ds.statement.statementSemantic(sc); + debugThrowWalker(ds.statement); sc.pop(); } result = ds.statement; @@ -4736,7 +4746,6 @@ private Statements* flatten(Statement statement, Scope* sc) if (dc) { s = new DebugStatement(cs.loc, cs.ifbody); - debugThrowWalker(cs.ifbody); } else s = cs.ifbody; @@ -4908,7 +4917,8 @@ Params: */ private void debugThrowWalker(Statement s) { - + if (!s) + return; extern(C++) final class DebugWalker : SemanticTimeTransitiveVisitor { alias visit = SemanticTimeTransitiveVisitor.visit; diff --git a/compiler/test/compilable/test16492.d b/compiler/test/compilable/debug_statement_attributes.d similarity index 73% rename from compiler/test/compilable/test16492.d rename to compiler/test/compilable/debug_statement_attributes.d index 833be1d8cf..bf762c001d 100644 --- a/compiler/test/compilable/test16492.d +++ b/compiler/test/compilable/debug_statement_attributes.d @@ -85,3 +85,17 @@ void test6() nothrow () {throw new Exception("");}(); } } + +void writeln() {} +void writeln(string) {} + +void test7() nothrow +{ + debug writeln("Hello"); // https://issues.dlang.org/show_bug.cgi?id=24017 + debug "Hello".writeln; + debug writeln = "Hello"; // https://github.com/dlang/dmd/issues/20719 + debug writeln; + + // https://github.com/dlang/dmd/pull/20720#issuecomment-2596892489 + debug pragma(msg, ""); // Came up as segfault, pragma statement became null after semantic +} diff --git a/compiler/test/compilable/test24017.d b/compiler/test/compilable/test24017.d deleted file mode 100644 index 0d03978120..0000000000 --- a/compiler/test/compilable/test24017.d +++ /dev/null @@ -1,11 +0,0 @@ -// https://issues.dlang.org/show_bug.cgi?id=24017 - -// REQUIRED_ARGS: -debug - -void writeln(string) {} - -void main() nothrow -{ - debug writeln("Hello"); - debug "Hello".writeln; -} From 72a934716553167a62d3c3289553a2e03692defa Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 24 Jan 2025 00:32:18 +0100 Subject: [PATCH 3/6] Fix #18281 - ICE on attempt to compare deref of two functions ptr (#20768) --- compiler/src/dmd/expressionsem.d | 17 +++++++++++++++++ compiler/test/fail_compilation/fail22151.d | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index ee8eb36465..b97f4578e8 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -13496,6 +13496,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor error(exp.loc, "compare not defined for complex operands"); return setError(); } + else if (t1.isTypeFunction() || t2.isTypeFunction()) + { + error(exp.loc, "comparison is not defined for function types"); + return setError(); + } else if (t1.ty == Taarray || t2.ty == Taarray) { error(exp.loc, "`%s` is not defined for associative arrays", EXPtoString(exp.op).ptr); @@ -13816,6 +13821,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + if (t1.isTypeFunction() || t2.isTypeFunction()) + { + error(exp.loc, "operator `==` is not defined for function types"); + return setError(); + } + if (auto tv = t1.isTypeVector()) exp.type = tv.toBooleanVector(); @@ -13877,6 +13888,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.e2.op == EXP.call) exp.e2 = (cast(CallExp)exp.e2).addDtorHook(sc); + if (exp.e1.type.isTypeFunction() || exp.e2.type.isTypeFunction()) + { + error(exp.loc, "operator `is` is not defined for function types"); + return setError(); + } + if (exp.e1.type.toBasetype().ty == Tsarray || exp.e2.type.toBasetype().ty == Tsarray) deprecation(exp.loc, "identity comparison of static arrays " diff --git a/compiler/test/fail_compilation/fail22151.d b/compiler/test/fail_compilation/fail22151.d index c6c3b1b742..9b5d5aad7b 100644 --- a/compiler/test/fail_compilation/fail22151.d +++ b/compiler/test/fail_compilation/fail22151.d @@ -2,10 +2,13 @@ /* TEST_OUTPUT: --- -fail_compilation/fail22151.d(14): Error: function `test` is not an lvalue and cannot be modified -fail_compilation/fail22151.d(15): Error: function `test2` is not an lvalue and cannot be modified -fail_compilation/fail22151.d(18): Error: function pointed to by `fp` is not an lvalue and cannot be modified -fail_compilation/fail22151.d(21): Error: function pointed to by `ff` is not an lvalue and cannot be modified +fail_compilation/fail22151.d(17): Error: function `test` is not an lvalue and cannot be modified +fail_compilation/fail22151.d(18): Error: function `test2` is not an lvalue and cannot be modified +fail_compilation/fail22151.d(21): Error: function pointed to by `fp` is not an lvalue and cannot be modified +fail_compilation/fail22151.d(24): Error: function pointed to by `ff` is not an lvalue and cannot be modified +fail_compilation/fail22151.d(27): Error: operator `==` is not defined for function types +fail_compilation/fail22151.d(28): Error: operator `is` is not defined for function types +fail_compilation/fail22151.d(29): Error: comparison is not defined for function types --- */ @@ -19,6 +22,11 @@ void test() auto ff = &test2; *ff = *&test2; + + // https://github.com/dlang/dmd/issues/18281 + const c = *fp == *fp; + const d = *fp is *fp; + const e = *fp < *fp; } void test2(); From eb083c06d9062148084c993f511835c73730c568 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Sun, 16 Feb 2025 00:27:18 +0100 Subject: [PATCH 4/6] Fix #20859 - ICE: class with __vtbl field name causes segfault in Scope::inCfile --- compiler/src/dmd/dsymbolsem.d | 3 ++- compiler/test/fail_compilation/test20859.d | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 compiler/test/fail_compilation/test20859.d diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index 77e03c3bc8..15557b7459 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -4137,7 +4137,8 @@ private extern(C++) class AddMemberVisitor : Visitor } // If using C tag/prototype/forward declaration rules - if (sc.flags & SCOPE.Cfile && !dsym.isImport()) + if (sc && sc.flags & SCOPE.Cfile && !dsym.isImport()) + // When merging master, replace with: if (sc && sc.inCfile && !dsym.isImport()) { if (handleTagSymbols(*sc, dsym, s2, sds)) return; diff --git a/compiler/test/fail_compilation/test20859.d b/compiler/test/fail_compilation/test20859.d new file mode 100644 index 0000000000..50fa9e0d49 --- /dev/null +++ b/compiler/test/fail_compilation/test20859.d @@ -0,0 +1,11 @@ +/** +TEST_OUTPUT: +--- +fail_compilation/test20859.d(8): Error: variable `test20859.ICE.__vtbl` conflicts with variable `test20859.ICE.__vtbl` at fail_compilation/test20859.d(10) +--- +*/ + +class ICE +{ + void **__vtbl; +} From 34cf3a95031408e747a0c904c0f98170d09244c6 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 19 Feb 2025 06:42:21 +0100 Subject: [PATCH 5/6] Fix #20894 (#20895) - pragma(msg) interprets printf format specifiers --- compiler/src/dmd/pragmasem.d | 2 +- compiler/test/compilable/bug11735.d | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/src/dmd/pragmasem.d b/compiler/src/dmd/pragmasem.d index 3a455fb3d1..eb84d83705 100644 --- a/compiler/src/dmd/pragmasem.d +++ b/compiler/src/dmd/pragmasem.d @@ -568,7 +568,7 @@ private bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args) else { buf.writestring("\n"); - fprintf(stderr, buf.extractChars); + fprintf(stderr, "%s", buf.extractChars); } return true; } diff --git a/compiler/test/compilable/bug11735.d b/compiler/test/compilable/bug11735.d index b94cb6e77d..be61a50585 100644 --- a/compiler/test/compilable/bug11735.d +++ b/compiler/test/compilable/bug11735.d @@ -13,6 +13,7 @@ print dstring foo_str foo_wstr foo_dstr +X%nY --- */ @@ -33,4 +34,7 @@ void main() pragma(msg, a); pragma(msg, b); pragma(msg, c); + + // https://github.com/dlang/dmd/issues/20894 + pragma(msg, "X%nY"); } From 3945e81615bf7baeb524667927c15ff2416303d5 Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 28 Feb 2025 21:46:10 +0100 Subject: [PATCH 6/6] Fix #20907 - DMD segfaults with static array length parameter derived from left-shifted template parameter property (#20919) --- compiler/test/runnable/template3.d | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/test/runnable/template3.d b/compiler/test/runnable/template3.d index e3313672d0..7b90cff29a 100644 --- a/compiler/test/runnable/template3.d +++ b/compiler/test/runnable/template3.d @@ -240,6 +240,16 @@ void test8() /*********************************************************/ +// https://github.com/dlang/dmd/issues/20907 +struct Bar { enum bar = 1; } +void foo(A)(A[], A[1 << A.bar]) {} +void test20907() +{ + foo((Bar[]).init, (Bar[2]).init); +} + +/*********************************************************/ + int main() { test1(); @@ -250,6 +260,7 @@ int main() test6(); test7(); test8(); + test20907(); printf("Success\n"); return 0;