diff --git a/CHANGELOG.md b/CHANGELOG.md index 10187542033..e090682c4ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # LDC master #### Big news -- Frontend, druntime and Phobos are at version [2.110.0](https://dlang.org/changelog/2.110.0.html). (#4707, #4737, #4749, #4768) +- Frontend, druntime and Phobos are at version [2.110.0](https://dlang.org/changelog/2.110.0.html). (#4707, #4737, #4749, #4768, #4784) - LLVM for prebuilt packages bumped to v18.1.8 (incl. macOS arm64). (#4712) - Android: NDK for prebuilt package bumped from r26d to r27. (#4711) - ldc2.conf: %%ldcconfigpath%% placeholder added - specifies the directory where current configuration file is located. (#4717) diff --git a/dmd/expressionsem.d b/dmd/expressionsem.d index e1781de4453..11a841b460f 100644 --- a/dmd/expressionsem.d +++ b/dmd/expressionsem.d @@ -14999,6 +14999,27 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) { return false; } + else if (sc._module.ident == Id.atomic && sc._module.parent !is null) + { + // Allow core.internal.atomic, it is an compiler implementation for a given platform module. + // It is then exposed by other modules such as core.atomic and core.stdc.atomic. + // This is available as long as druntime is on the import path and the platform supports that operation. + + // https://issues.dlang.org/show_bug.cgi?id=24846 + + Package parent = sc._module.parent.isPackage(); + if (parent !is null) + { + // This can be easily converted over to apply to core.atomic and core.internal.atomic + if (parent.ident == Id.internal) + { + parent = parent.parent.isPackage(); + + if (parent !is null && parent.ident == Id.core && parent.parent is null) + return false; + } + } + } //printf("checkSharedAccess() `%s` returnRef: %d\n", e.toChars(), returnRef); diff --git a/dmd/frontend.h b/dmd/frontend.h index 845e4889e95..46b0efd8d16 100644 --- a/dmd/frontend.h +++ b/dmd/frontend.h @@ -8606,6 +8606,7 @@ struct Id final static Identifier* va_start; static Identifier* std; static Identifier* core; + static Identifier* internal; static Identifier* config; static Identifier* c_complex_float; static Identifier* c_complex_double; diff --git a/dmd/id.d b/dmd/id.d index 50273798458..2a03ce9314a 100644 --- a/dmd/id.d +++ b/dmd/id.d @@ -389,6 +389,7 @@ immutable Msgtable[] msgtable = // Builtin functions { "std" }, { "core" }, + { "internal" }, { "config" }, { "c_complex_float" }, { "c_complex_double" }, diff --git a/dmd/lexer.d b/dmd/lexer.d index 9dbd6c85e29..a783e0a5087 100644 --- a/dmd/lexer.d +++ b/dmd/lexer.d @@ -1556,6 +1556,8 @@ class Lexer if (ndigits != 2 && !utf_isValidDchar(v)) { error(loc, "invalid UTF character \\U%08x", v); + if (v >= 0xD800 && v <= 0xDFFF) + errorSupplemental("The code unit is a UTF-16 surrogate, is the escape UTF-16 not a Unicode code point?"); v = '?'; // recover with valid UTF character } } @@ -3172,6 +3174,11 @@ version (IN_LLVM) { /* *always* map C `long double` literals to D `real` ones */ eSink.error(loc, format, args); } + void errorSupplemental(T...)(const(char)* format, T args) + { + eSink.errorSupplemental(token.loc, format, args); + } + void deprecation(T...)(const ref Loc loc, const(char)* format, T args) { eSink.deprecation(loc, format, args); @@ -3675,6 +3682,7 @@ unittest import core.stdc.stdarg; string expected; + string expectedSupplemental; bool gotError; void error(const ref Loc loc, const(char)* format, ...) @@ -3687,13 +3695,25 @@ unittest va_end(ap); assert(expected == actual); } + + void errorSupplemental(const ref Loc loc, const(char)* format, ...) + { + gotError = true; + char[128] buffer = void; + va_list ap; + va_start(ap, format); + auto actual = buffer[0 .. vsnprintf(buffer.ptr, buffer.length, format, ap)]; + va_end(ap); + assert(expectedSupplemental == actual); + } } ErrorSinkTest errorSink = new ErrorSinkTest; - void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength, bool Ccompile = false) + void test2(string sequence, string[2] expectedError, dchar expectedReturnValue, uint expectedScanLength, bool Ccompile = false) { - errorSink.expected = expectedError; + errorSink.expected = expectedError[0]; + errorSink.expectedSupplemental = expectedError[1]; errorSink.gotError = false; auto p = cast(const(char)*)sequence.ptr; Lexer lexer = new Lexer(errorSink); @@ -3706,6 +3726,11 @@ unittest assert(expectedScanLength == actualScanLength); } + void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength, bool Ccompile = false) + { + test2(sequence, [expectedError, null], expectedReturnValue, expectedScanLength, Ccompile); + } + test("c", `undefined escape sequence \c`, 'c', 1); test("!", `undefined escape sequence \!`, '!', 1); test(""", `undefined escape sequence \&`, '&', 1, true); @@ -3724,8 +3749,6 @@ unittest test("U0001f6" , `escape hex sequence has 6 hex digits instead of 8`, 0x0001f6, 7); test("U0001f60", `escape hex sequence has 7 hex digits instead of 8`, 0x0001f60, 8); - test("ud800" , `invalid UTF character \U0000d800`, '?', 5); - test("udfff" , `invalid UTF character \U0000dfff`, '?', 5); test("U00110000", `invalid UTF character \U00110000`, '?', 9); test("xg0" , `undefined escape hex sequence \xg`, 'g', 2); @@ -3737,6 +3760,9 @@ unittest test(""", `unterminated named entity "`, '?', 5); test("400", `escape octal sequence \400 is larger than \377`, 0x100, 3); + + test2("uD800", [`invalid UTF character \U0000d800`, `The code unit is a UTF-16 surrogate, is the escape UTF-16 not a Unicode code point?`], '?', 5); + test2("uDFFF", [`invalid UTF character \U0000dfff`, `The code unit is a UTF-16 surrogate, is the escape UTF-16 not a Unicode code point?`], '?', 5); } unittest diff --git a/runtime/phobos b/runtime/phobos index b7faca1c9bc..e6d14f51518 160000 --- a/runtime/phobos +++ b/runtime/phobos @@ -1 +1 @@ -Subproject commit b7faca1c9bca5ed31ab82b0700ae45ca312727d7 +Subproject commit e6d14f51518719988db1b83ab7af541dc4824e95 diff --git a/tests/dmd/compilable/atomic_store_2_shared_classes.d b/tests/dmd/compilable/atomic_loadstore_shared_classes.d similarity index 60% rename from tests/dmd/compilable/atomic_store_2_shared_classes.d rename to tests/dmd/compilable/atomic_loadstore_shared_classes.d index 0d8cd748937..f719aa829f0 100644 --- a/tests/dmd/compilable/atomic_store_2_shared_classes.d +++ b/tests/dmd/compilable/atomic_loadstore_shared_classes.d @@ -5,9 +5,14 @@ class Foo { } +shared Foo toLoad; + void oops() { auto f0 = new shared Foo; auto f1 = new shared Foo; atomicStore(f0, f1); + + // https://issues.dlang.org/show_bug.cgi?id=24846 + shared(Foo) f2 = atomicLoad(toLoad); } diff --git a/tests/dmd/compilable/stdcheaders.c b/tests/dmd/compilable/stdcheaders.c index 8405469ff49..9641f5725e0 100644 --- a/tests/dmd/compilable/stdcheaders.c +++ b/tests/dmd/compilable/stdcheaders.c @@ -23,8 +23,10 @@ #ifndef __APPLE__ // /Applications/Xcode-14.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tgmath.h(39): Error: named parameter required before `...` #include +#ifndef _MSC_VER // C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt\corecrt_math.h(93): Error: reinterpretation through overlapped field `f` is not allowed in CTFE float x = NAN; #endif +#endif #ifndef _MSC_VER // setjmp.h(51): Error: missing tag `identifier` after `struct #include