Hi,

This patch backports r11-445 to the gcc-10 release branch.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed.

Regards,
Iain.

---
libphobos/ChangeLog:

        PR d/95166
        * libdruntime/core/cpuid.d (cpuidX86): Do not use i7 detection on AMD
        processors.
        (hasCPUID): Fix deprecated asm syntax.

        PR d/95167
        * src/std/zip.d (unittest): Skip test if unzip is not installed.

        PR d/95168
        * src/std/net/curl.d (HTTP.onReceiveHeader): Move status line parsing
        to ...
        (HTTP.parseStatusLine): ... here.  New function.  Add support for
        parsing HTTP/2 status lines.
---
 libphobos/libdruntime/core/cpuid.d | 18 ++++++++++--
 libphobos/src/std/net/curl.d       | 44 ++++++++++++++++++++++--------
 libphobos/src/std/zip.d            |  6 ++++
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/libphobos/libdruntime/core/cpuid.d 
b/libphobos/libdruntime/core/cpuid.d
index 839605aee1e..2ba13b55bf1 100644
--- a/libphobos/libdruntime/core/cpuid.d
+++ b/libphobos/libdruntime/core/cpuid.d
@@ -941,13 +941,27 @@ void cpuidX86()
             datacache[0].lineSize = 32;
         }
     }
-    if (max_cpuid >= 0x0B) {
+    if (cf.probablyIntel && max_cpuid >= 0x0B) {
         // For Intel i7 and later, use function 0x0B to determine
         // cores and hyperthreads.
         getCpuInfo0B();
     } else {
         if (hyperThreadingBit) cf.maxThreads = (apic>>>16) & 0xFF;
         else cf.maxThreads = cf.maxCores;
+
+        if (cf.probablyAMD && max_extended_cpuid >= 0x8000_001E) {
+            version (GNU) asm pure nothrow @nogc {
+                "cpuid" : "=a" (a), "=b" (b) : "a" (0x8000_001E) : "ecx", 
"edx";
+            } else {
+                asm pure nothrow @nogc {
+                    mov EAX, 0x8000_001e;
+                    cpuid;
+                    mov b, EBX;
+                }
+            }
+            ubyte coresPerComputeUnit = ((b >> 8) & 3) + 1;
+            cf.maxCores = cf.maxThreads / coresPerComputeUnit;
+        }
     }
 }
 
@@ -975,7 +989,7 @@ bool hasCPUID()
                 xor {(%%esp), %%eax|eax, [esp]}
                                            # eax = whichever bits were changed
                 popf{l|d}                  # Restore original EFLAGS
-                " : "=a" flags;
+                " : "=a" (flags);
             }
         }
         else version (D_InlineAsm_X86)
diff --git a/libphobos/src/std/net/curl.d b/libphobos/src/std/net/curl.d
index 32ba45ce2de..445f996ea08 100644
--- a/libphobos/src/std/net/curl.d
+++ b/libphobos/src/std/net/curl.d
@@ -2451,7 +2451,6 @@ struct HTTP
                                                      in char[] value) callback)
         {
             import std.algorithm.searching : startsWith;
-            import std.conv : to;
             import std.regex : regex, match;
             import std.uni : toLower;
 
@@ -2471,18 +2470,8 @@ struct HTTP
                     if (header.startsWith("HTTP/"))
                     {
                         headersIn.clear();
-
-                        const m = match(header, regex(r"^HTTP/(\d+)\.(\d+) 
(\d+) (.*)$"));
-                        if (m.empty)
+                        if (parseStatusLine(header, status))
                         {
-                            // Invalid status line
-                        }
-                        else
-                        {
-                            status.majorVersion = to!ushort(m.captures[1]);
-                            status.minorVersion = to!ushort(m.captures[2]);
-                            status.code = to!ushort(m.captures[3]);
-                            status.reason = m.captures[4].idup;
                             if (onReceiveStatusLine != null)
                                 onReceiveStatusLine(status);
                         }
@@ -2517,6 +2506,37 @@ struct HTTP
 
     private RefCounted!Impl p;
 
+    /// Parse status line, as received from / generated by cURL.
+    private static bool parseStatusLine(in char[] header, out StatusLine 
status) @safe
+    {
+        import std.conv : to;
+        import std.regex : regex, match;
+
+        const m = match(header, regex(r"^HTTP/(\d+)(?:\.(\d+))? (\d+)(?: 
(.*))?$"));
+        if (m.empty)
+            return false; // Invalid status line
+        else
+        {
+            status.majorVersion = to!ushort(m.captures[1]);
+            status.minorVersion = m.captures[2].length ? 
to!ushort(m.captures[2]) : 0;
+            status.code = to!ushort(m.captures[3]);
+            status.reason = m.captures[4].idup;
+            return true;
+        }
+    }
+
+    @safe unittest
+    {
+        StatusLine status;
+        assert(parseStatusLine("HTTP/1.1 200 OK", status)
+            && status == StatusLine(1, 1, 200, "OK"));
+        assert(parseStatusLine("HTTP/1.0 304 Not Modified", status)
+            && status == StatusLine(1, 0, 304, "Not Modified"));
+        // The HTTP2 protocol is binary; cURL generates this fake text header.
+        assert(parseStatusLine("HTTP/2 200", status)
+            && status == StatusLine(2, 0, 200, null));
+    }
+
     /** Time condition enumeration as an alias of $(REF CurlTimeCond, 
etc,c,curl)
 
         $(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, 
_RFC2616 Section 14.25)
diff --git a/libphobos/src/std/zip.d b/libphobos/src/std/zip.d
index db47ddef0c9..8b130ea2dd9 100644
--- a/libphobos/src/std/zip.d
+++ b/libphobos/src/std/zip.d
@@ -970,6 +970,12 @@ version (Posix) @system unittest
 {
     import std.datetime, std.file, std.format, std.path, std.process, 
std.stdio;
 
+    if (executeShell("unzip").status != 0)
+    {
+        writeln("Can't run unzip, skipping unzip test");
+        return;
+    }
+
     auto zr = new ZipArchive();
     auto am = new ArchiveMember();
     am.compressionMethod = CompressionMethod.deflate;
-- 
2.20.1

Reply via email to