diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b3fcb82b07..69d289f317 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,8 +58,9 @@ jobs: # os: macos-13 # host_dmd: dmd # coverage: true - - job_name: macOS 12 x64, DMD (bootstrap) - os: macos-12 + - job_name: macOS 13 x64, DMD (bootstrap) + os: macos-13 + xcode: '14.3.1' # work around 'ld: multiple errors: symbol count from symbol table and dynamic symbol table differ' with old bootstrap compiler # de-facto bootstrap version on OSX # See: https://github.com/dlang/dmd/pull/13890 host_dmd: dmd-2.099.1 @@ -100,12 +101,9 @@ jobs: if: runner.os != 'Windows' run: ${{ runner.os == 'macOS' && 'ci/cirrusci.sh' || 'sudo -E ci/cirrusci.sh' }} - # NOTE: Linker ICEs with Xcode 15.0.1 (default version on macos-13) - # * https://issues.dlang.org/show_bug.cgi?id=24407 - # Remove this step if the default gets changed to 15.1 in actions/runner-images. - - name: 'macOS 13: Switch to Xcode v15.1' - if: matrix.os == 'macos-13' - run: sudo xcode-select -switch /Applications/Xcode_15.1.app + - name: 'macOS: Switch Xcode version if required' + if: runner.os == 'macOS' && matrix.xcode + run: sudo xcode-select -switch /Applications/Xcode_${{ matrix.xcode }}.app - name: 'Posix: Install host compiler' if: runner.os != 'Windows' diff --git a/.github/workflows/runnable_cxx.yml b/.github/workflows/runnable_cxx.yml index dc701907cd..224ae6fd85 100644 --- a/.github/workflows/runnable_cxx.yml +++ b/.github/workflows/runnable_cxx.yml @@ -57,10 +57,10 @@ jobs: # very few PRs actually benefit from this. fail-fast: false matrix: - os: [ macOS-12, ubuntu-20.04, windows-2019 ] + os: [ macos-13, ubuntu-20.04, windows-2019 ] target: [ - # Versions of clang earlier than 11 are not available on 20.04, but are on macOS-12 + # Versions of clang earlier than 11 are not available on 20.04, but are on macOS 13 clang-13.0.0, clang-12.0.0, clang-11.0.0, clang-10.0.0, clang-9.0.0, clang-8.0.0, # For g++, we test the oldest compiler on Ubuntu 20.04, which is GCC-9 g++-11, g++-10, g++-9, @@ -81,13 +81,13 @@ jobs: - { os: ubuntu-20.04, target: msvc-2015 } - { os: ubuntu-20.04, target: msvc-2013 } # OSX only supports clang - - { os: macOS-12, target: g++-11 } - - { os: macOS-12, target: g++-10 } - - { os: macOS-12, target: g++-9 } - - { os: macOS-12, target: msvc-2019 } - - { os: macOS-12, target: msvc-2017 } - - { os: macOS-12, target: msvc-2015 } - - { os: macOS-12, target: msvc-2013 } + - { os: macos-13, target: g++-11 } + - { os: macos-13, target: g++-10 } + - { os: macos-13, target: g++-9 } + - { os: macos-13, target: msvc-2019 } + - { os: macos-13, target: msvc-2017 } + - { os: macos-13, target: msvc-2015 } + - { os: macos-13, target: msvc-2013 } # We don't test g++ on Windows as DMD only mangles for MSVC - { os: windows-2019, target: g++-11 } - { os: windows-2019, target: g++-10 } @@ -126,13 +126,13 @@ jobs: - { target: g++-9, compiler: g++, cxx-version: 9.4.0, major: 9 } # Platform boilerplate - { os: ubuntu-20.04, arch: x86_64-linux-gnu-ubuntu-20.04 } - - { os: macOS-12, arch: x86_64-apple-darwin } + - { os: macos-13, arch: x86_64-apple-darwin } # Clang 9.0.0 have a different arch for OSX - - { os: macOS-12, target: clang-9.0.0, arch: x86_64-darwin-apple } + - { os: macos-13, target: clang-9.0.0, arch: x86_64-darwin-apple } # Those targets will generate artifacts that can be used by other testers - { storeArtifacts: false } - { os: ubuntu-20.04, target: g++-9, storeArtifacts: true } - - { os: macOS-12, target: clang-9.0.0, storeArtifacts: true } + - { os: macos-13, target: clang-9.0.0, storeArtifacts: true } #- { os: windows-2019, target: msvc-2019, storeArtifacts: true } # We're using the latest available images at the time of this commit. @@ -209,7 +209,7 @@ jobs: # On OSX, the system header are installed via `xcode-select` and not distributed with clang # Since some part of the testsuite rely on CC and CXX being only a binary (not a command), # and config files where only introduced from 6.0.0, use a wrapper script. - if [ "${{ matrix.os }}" == "macOS-12" ]; then + if [ "${{ matrix.os }}" == "macos-13" ]; then # Note: heredoc shouldn't be indented cat << 'EOF' > ${TMP_CC}-wrapper #!/bin/bash @@ -227,11 +227,15 @@ jobs: chmod +x ${TMP_CC}-wrapper ${TMP_CC}++-wrapper fi + - name: 'macOS 13: Switch to Xcode v14.3.1' # to work around '-macosx_version_min has been renamed to -macos_version_min' with some clang versions + if: matrix.os == 'macos-13' + run: sudo xcode-select -switch /Applications/Xcode_14.3.1.app + - name: '[Posix] Setup environment variables' if: matrix.compiler == 'clang' && runner.os != 'Windows' run: | TMP_CC='${{ github.workspace }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}/bin/clang' - if [ "${{ matrix.os }}" == "macOS-12" ]; then + if [ "${{ matrix.os }}" == "macos-13" ]; then echo "CC=${TMP_CC}-wrapper" >> $GITHUB_ENV echo "CXX=${TMP_CC}++-wrapper" >> $GITHUB_ENV echo "SDKROOT=$(xcrun --show-sdk-path)" >> $GITHUB_ENV diff --git a/ci/README.md b/ci/README.md index ec1c6bf5ba..d9f989dc11 100644 --- a/ci/README.md +++ b/ci/README.md @@ -112,12 +112,12 @@ The auto tester tests DMD on various Posix platforms. **Config**: [azure-pipelines.yml](https://github.com/dlang/dmd/blob/master/.github/workflows/runnable_cxx.yml) **Checks**: -- C++ interop tests / Run (macOS-12, clang-13.0.0) -- C++ interop tests / Run (macOS-12, clang-12.0.0) -- C++ interop tests / Run (macOS-12, clang-11.0.0) -- C++ interop tests / Run (macOS-12, clang-10.0.0) -- C++ interop tests / Run (macOS-12, clang-9.0.0) -- C++ interop tests / Run (macOS-12, clang-8.0.0) +- C++ interop tests / Run (macos-13, clang-13.0.0) +- C++ interop tests / Run (macos-13, clang-12.0.0) +- C++ interop tests / Run (macos-13, clang-11.0.0) +- C++ interop tests / Run (macos-13, clang-10.0.0) +- C++ interop tests / Run (macos-13, clang-9.0.0) +- C++ interop tests / Run (macos-13, clang-8.0.0) - C++ interop tests / Run (ubuntu-20.04, clang-13.0.0) - C++ interop tests / Run (ubuntu-20.04, clang-12.0.0) - C++ interop tests / Run (ubuntu-20.04, clang-11.0.0) diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index 34b120b341..b08e2bed2d 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -2335,7 +2335,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) Type tb = t.toBasetype(); Type typeb = e.type.toBasetype(); - if (e.hexString && !e.committed) + if (e.hexString && !e.committed && tb.nextOf().isintegral) { const szx = cast(ubyte) tb.nextOf().size(); if (szx != se.sz && (e.len % szx) == 0) diff --git a/compiler/src/dmd/dinterpret.d b/compiler/src/dmd/dinterpret.d index 4e04a27214..1184fb9516 100644 --- a/compiler/src/dmd/dinterpret.d +++ b/compiler/src/dmd/dinterpret.d @@ -6132,7 +6132,7 @@ public: { auto se = e1.isStringExp(); // Allow casting a hex string literal to short[], int[] or long[] - if (se && se.hexString && se.postfix == StringExp.NoPostfix) + if (se && se.hexString && se.postfix == StringExp.NoPostfix && e.to.nextOf().isintegral) { const sz = cast(size_t) e.to.nextOf().size; if ((se.len % sz) != 0) diff --git a/compiler/src/dmd/enumsem.d b/compiler/src/dmd/enumsem.d index 99211e4985..e22bdba349 100644 --- a/compiler/src/dmd/enumsem.d +++ b/compiler/src/dmd/enumsem.d @@ -185,7 +185,7 @@ void enumSemantic(Scope* sc, EnumDeclaration ed) if (ed.members.length == 0) { - .error(ed.loc, "%s `%s enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars()); + .error(ed.loc, "%s `%s` enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars()); ed.errors = true; ed.semanticRun = PASS.semanticdone; return; diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 6e2aeb46ed..86a35cf05b 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -15067,6 +15067,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/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 364dcb3fac..44f65921ea 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -8836,6 +8836,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/compiler/src/dmd/id.d b/compiler/src/dmd/id.d index b60172d051..3aacc9cc98 100644 --- a/compiler/src/dmd/id.d +++ b/compiler/src/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/compiler/src/dmd/lexer.d b/compiler/src/dmd/lexer.d index 476a700bde..95eef80cd0 100644 --- a/compiler/src/dmd/lexer.d +++ b/compiler/src/dmd/lexer.d @@ -1555,6 +1555,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 } } @@ -3168,6 +3170,11 @@ class Lexer 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); @@ -3671,6 +3678,7 @@ unittest import core.stdc.stdarg; string expected; + string expectedSupplemental; bool gotError; void error(const ref Loc loc, const(char)* format, ...) @@ -3683,13 +3691,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); @@ -3702,6 +3722,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); @@ -3720,8 +3745,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); @@ -3733,6 +3756,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/compiler/test/compilable/atomic_store_2_shared_classes.d b/compiler/test/compilable/atomic_loadstore_shared_classes.d similarity index 60% rename from compiler/test/compilable/atomic_store_2_shared_classes.d rename to compiler/test/compilable/atomic_loadstore_shared_classes.d index 0d8cd74893..f719aa829f 100644 --- a/compiler/test/compilable/atomic_store_2_shared_classes.d +++ b/compiler/test/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/compiler/test/fail_compilation/diag24812.d b/compiler/test/fail_compilation/diag24812.d new file mode 100644 index 0000000000..626f47ebf0 --- /dev/null +++ b/compiler/test/fail_compilation/diag24812.d @@ -0,0 +1,7 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/diag24812.d(7): Error: enum `diag24812.Foo` enum `Foo` must have at least one member +--- +*/ +enum Foo {} diff --git a/compiler/test/fail_compilation/hexstring.d b/compiler/test/fail_compilation/hexstring.d index 0f23f44438..edbb4e67bc 100644 --- a/compiler/test/fail_compilation/hexstring.d +++ b/compiler/test/fail_compilation/hexstring.d @@ -14,6 +14,7 @@ fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex str fail_compilation/hexstring.d(40): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5 fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"11223344"d` of type `dstring` to `immutable(float[])` fail_compilation/hexstring.d(42): Error: cannot implicitly convert expression `x"1122"w` of type `wstring` to `immutable(ubyte[])` +fail_compilation/hexstring.d(50): Error: array cast from `string` to `S[]` is not supported at compile time fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]` --- */ @@ -21,7 +22,6 @@ immutable ubyte[] s0 = x"123F"; static assert(s0[0] == 0x12); static assert(s0[1] == 0x3F); immutable byte[] s1 = x"123F"; - enum E(X) = cast(X[]) x"AABBCCDD"; static assert(E!int[0] == 0xAABBCCDD); @@ -40,3 +40,11 @@ immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c; immutable uint[] f12 = x"1122334455"d; immutable float[] f13 = x"11223344"d; immutable ubyte[] f14 = x"1122"w; + +// https://issues.dlang.org/show_bug.cgi?id=24832 +struct S +{ + ushort l0, l1, l2, l3, l4, l5; +} + +immutable S[] returnValues = cast(S[]) x"FFFFFFFFFFFFFFFFFFFFFFFF"; diff --git a/druntime/src/importc.h b/druntime/src/importc.h index 858e502b99..b7b82dbe6b 100644 --- a/druntime/src/importc.h +++ b/druntime/src/importc.h @@ -41,6 +41,7 @@ #define __alignof _Alignof #define __vector_size__ vector_size #define __typeof typeof +#define __typeof__ typeof /******************** * Clang nullability extension used by macOS headers.