gdb: Update producer check for Intel compilers.
authorFelix Willgerodt <felix.willgerodt@intel.com>
Thu, 8 Apr 2021 07:15:58 +0000 (09:15 +0200)
committerFelix Willgerodt <felix.willgerodt@intel.com>
Thu, 8 Apr 2021 07:18:55 +0000 (09:18 +0200)
The main goal of this patch is to get rid of a warning for the new Fortran
compiler:

(gdb) b 9
warning: Could not recognize version of Intel Compiler in: "Intel(R) Fortran 21.0-2087b"
Breakpoint 1 at 0x4048cf: file comp.f90, line 9.

While trying to fix this I analyzed DW_AT_producer of all latest Intel
compilers for C, C++ and Fortran.  They do no longer necessarily start with
"Intel (R)" nor do they follow the internal and external version number
scheme that the original patch for this check assumed.  Some newer compilers
even contradict the "intermediate" digit in the old version scheme and have
the MINOR number as the second digit, even when having 3 or 4 digits overall.

Therefore I rewrote the check to consider the first MAJOR.MINOR string found
as the version number.  This might not be 100% correct for some older
internal compilers, but the only current user of this function is only
checking for the major version anyway.  Hence this should be reliable enough
and extendable enough going forward.

gdb/ChangeLog:
2021-04-08  Felix Willgerodt  <felix.willgerodt@intel.com>

     * producer.c: (producer_is_icc): Update for new version scheme.
     (producer_parsing_tests): Update names and expected results.
     * producer.h: (producer_is_icc): Update comment accordingly.

gdb/ChangeLog
gdb/producer.c
gdb/producer.h

index 332688cd586ad099ebe0f04ea2b5f70c0c11174a..6fc98a74946cb092bd3a7e7db6d3c89a56cd6561 100644 (file)
@@ -1,3 +1,9 @@
+2021-04-08  Felix Willgerodt  <felix.willgerodt@intel.com>
+
+       * producer.c: (producer_is_icc): Update for new version scheme.
+       (producer_parsing_tests): Update names and expected results.
+       * producer.h: (producer_is_icc): Update comment accordingly.
+
 2021-04-07  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * target.h (struct target_ops) <follow_fork>: Return void.
index fcfd7b9b807122b1fbbd7199b69b94fb01ce88ca..1cda48c204ac99be312dbead0c20fa57aba4de01 100644 (file)
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "producer.h"
 #include "gdbsupport/selftest.h"
+#include <regex>
 
 /* See producer.h.  */
 
@@ -78,50 +79,30 @@ producer_is_gcc (const char *producer, int *major, int *minor)
 bool
 producer_is_icc (const char *producer, int *major, int *minor)
 {
-  if (producer == NULL || !startswith (producer, "Intel(R)"))
+  std::regex i_re ("Intel\\(R\\)");
+  std::cmatch i_m;
+  if ((producer == nullptr) || !std::regex_search (producer, i_m, i_re))
     return false;
 
   /* Prepare the used fields.  */
   int maj, min;
-  if (major == NULL)
+  if (major == nullptr)
     major = &maj;
-  if (minor == NULL)
+  if (minor == nullptr)
     minor = &min;
 
   *minor = 0;
   *major = 0;
 
-  /* Consumes the string till a "Version" is found.  */
-  const char *cs = strstr (producer, "Version");
-  if (cs != NULL)
-    {
-      cs = skip_to_space (cs);
-
-      int intermediate = 0;
-      int nof = sscanf (cs, "%d.%d.%d.%*d", major, &intermediate, minor);
-
-      /* Internal versions are represented only as MAJOR.MINOR, where
-        minor is usually 0.
-        Public versions have 3 fields as described with the command
-        above.  */
-      if (nof == 3)
-       return true;
-
-      if (nof == 2)
-       {
-         *minor = intermediate;
-         return true;
-       }
-    }
+  std::regex re ("[0-9]+\\.[0-9]+");
+  std::cmatch version;
 
-  static bool warning_printed = false;
-  /* Not recognized as Intel, let the user know.  */
-  if (!warning_printed)
+  if (std::regex_search (producer, version, re))
     {
-      warning (_("Could not recognize version of Intel Compiler in: \"%s\""),
-              producer);
-      warning_printed = true;
+      sscanf (version.str ().c_str (), "%d.%d", major, minor);
+      return true;
     }
+
   return false;
 }
 
@@ -152,15 +133,15 @@ producer_parsing_tests ()
   }
 
   {
-    static const char extern_f_14_1[] = "\
+    static const char extern_f_14_0[] = "\
 Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
 Intel(R) 64, \
 Version 14.0.1.074 Build 20130716";
 
     int major = 0, minor = 0;
-    SELF_CHECK (producer_is_icc (extern_f_14_1, &major, &minor)
-               && major == 14 && minor == 1);
-    SELF_CHECK (!producer_is_gcc (extern_f_14_1, &major, &minor));
+    SELF_CHECK (producer_is_icc (extern_f_14_0, &major, &minor)
+               && major == 14 && minor == 0);
+    SELF_CHECK (!producer_is_gcc (extern_f_14_0, &major, &minor));
   }
 
   {
index 15a60dc0ab5cf938c36d78303880666fd688a55c..9cfccd633713c598e48290d7e0a5be1deebd6872 100644 (file)
@@ -31,25 +31,7 @@ extern int producer_is_gcc_ge_4 (const char *producer);
 extern int producer_is_gcc (const char *producer, int *major, int *minor);
 
 /* Returns true if the given PRODUCER string is Intel or false
-   otherwise.  Sets the MAJOR and MINOR versions when not NULL.
-
-   Internal and external ICC versions have to be taken into account.
-   PRODUCER strings for internal releases are slightly different than
-   for public ones.  Internal releases have a major release number and
-   0 as minor release.  External releases have 4 fields, 3 of them are
-   not 0 and only two are of interest, major and update.
-
-   Examples are:
-
-     Public release:
-       "Intel(R) Fortran Intel(R) 64 Compiler XE for applications
-       running on Intel(R) 64, Version 14.0.1.074 Build 20130716";
-       "Intel(R) C++ Intel(R) 64 Compiler XE for applications
-       running on Intel(R) 64, Version 14.0.1.074 Build 20130716";
-
-    Internal releases:
-      "Intel(R) C++ Intel(R) 64 Compiler for applications
-       running on Intel(R) 64, Version 18.0 Beta ....".  */
+   otherwise.  Sets the MAJOR and MINOR versions when not NULL.  */
 extern bool producer_is_icc (const char *producer, int *major, int *minor);
 
 /* Returns true if the given PRODUCER string is LLVM (clang/flang) or