mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-27 10:23:55 +08:00
dwarf2read: Restrict ICC workaround to ICC<14
GDB has a workaround for DWARF output by ICC, related to missing DW_AT_declaration on incomplete types. The bug was fixed in ICC 14, so this commit adjusts GDB accordingly. For the version check, this adds a new parser function for the ICC producer string. While at it, it also adds unit tests for the producer parsing covering the new function and preexisting parsers. gdb/ChangeLog: 2017-09-26 Walfred Tedeschi <walfred.tedeschi@intel.com> Pedro Alves <palves@redhat.com> * dwarf2read.c (dwarf2_cu): Remove field producer_is_icc and add producer_is_icc_lt_14. (producer_is_icc_lt_14): New function. (check_producer): Add code for checking version of ICC. (producer_is_icc): Move to producer.c. (read_structure_type): Restrict ICC workaround to ICC<14. * producer.c: Include selftest.h. (producer_is_icc, producer_parsing_tests, _initialize_producer): New functions. * producer.h (producer_is_icc): New declaration.
This commit is contained in:
parent
b32b108aba
commit
5230b05a94
@ -1,3 +1,17 @@
|
||||
2017-09-26 Walfred Tedeschi <walfred.tedeschi@intel.com>
|
||||
Pedro Alves <palves@redhat.com>
|
||||
|
||||
* dwarf2read.c (dwarf2_cu): Remove field producer_is_icc and add
|
||||
producer_is_icc_lt_14.
|
||||
(producer_is_icc_lt_14): New function.
|
||||
(check_producer): Add code for checking version of ICC.
|
||||
(producer_is_icc): Move to producer.c.
|
||||
(read_structure_type): Restrict ICC workaround to ICC<14.
|
||||
* producer.c: Include selftest.h.
|
||||
(producer_is_icc, producer_parsing_tests, _initialize_producer):
|
||||
New functions.
|
||||
* producer.h (producer_is_icc): New declaration.
|
||||
|
||||
2017-09-26 Walfred Tedeschi <walfred.tedeschi@intel.com>
|
||||
|
||||
* Makefile.in (SFILES): Add producer.c.
|
||||
|
@ -603,7 +603,7 @@ struct dwarf2_cu
|
||||
unsigned int checked_producer : 1;
|
||||
unsigned int producer_is_gxx_lt_4_6 : 1;
|
||||
unsigned int producer_is_gcc_lt_4_3 : 1;
|
||||
unsigned int producer_is_icc : 1;
|
||||
unsigned int producer_is_icc_lt_14 : 1;
|
||||
|
||||
/* When set, the file that we're processing is known to have
|
||||
debugging info for C++ namespaces. GCC 3.3.x did not produce
|
||||
@ -9348,6 +9348,19 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
|
||||
&objfile->objfile_obstack);
|
||||
}
|
||||
|
||||
/* ICC<14 does not output the required DW_AT_declaration on incomplete
|
||||
types, but gives them a size of zero. Starting with version 14,
|
||||
ICC is compatible with GCC. */
|
||||
|
||||
static int
|
||||
producer_is_icc_lt_14 (struct dwarf2_cu *cu)
|
||||
{
|
||||
if (!cu->checked_producer)
|
||||
check_producer (cu);
|
||||
|
||||
return cu->producer_is_icc_lt_14;
|
||||
}
|
||||
|
||||
/* Check for possibly missing DW_AT_comp_dir with relative .debug_line
|
||||
directory paths. GCC SVN r127613 (new option -fdebug-prefix-map) fixed
|
||||
this, it was first present in GCC release 4.3.0. */
|
||||
@ -12853,8 +12866,8 @@ check_producer (struct dwarf2_cu *cu)
|
||||
cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
|
||||
cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
|
||||
}
|
||||
else if (startswith (cu->producer, "Intel(R) C"))
|
||||
cu->producer_is_icc = 1;
|
||||
else if (producer_is_icc (cu->producer, &major, &minor))
|
||||
cu->producer_is_icc_lt_14 = major < 14;
|
||||
else
|
||||
{
|
||||
/* For other non-GCC compilers, expect their behavior is DWARF version
|
||||
@ -13595,17 +13608,6 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
|
||||
smash_to_methodptr_type (type, new_type);
|
||||
}
|
||||
|
||||
/* Return non-zero if the CU's PRODUCER string matches the Intel C/C++ compiler
|
||||
(icc). */
|
||||
|
||||
static int
|
||||
producer_is_icc (struct dwarf2_cu *cu)
|
||||
{
|
||||
if (!cu->checked_producer)
|
||||
check_producer (cu);
|
||||
|
||||
return cu->producer_is_icc;
|
||||
}
|
||||
|
||||
/* Called when we find the DIE that starts a structure or union scope
|
||||
(definition) to create a type for the structure or union. Fill in
|
||||
@ -13711,10 +13713,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||
TYPE_LENGTH (type) = 0;
|
||||
}
|
||||
|
||||
if (producer_is_icc (cu) && (TYPE_LENGTH (type) == 0))
|
||||
if (producer_is_icc_lt_14 (cu) && (TYPE_LENGTH (type) == 0))
|
||||
{
|
||||
/* ICC does not output the required DW_AT_declaration
|
||||
on incomplete types, but gives them a size of zero. */
|
||||
/* ICC<14 does not output the required DW_AT_declaration on
|
||||
incomplete types, but gives them a size of zero. */
|
||||
TYPE_STUB (type) = 1;
|
||||
}
|
||||
else
|
||||
|
145
gdb/producer.c
145
gdb/producer.c
@ -19,6 +19,7 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "producer.h"
|
||||
#include "selftest.h"
|
||||
|
||||
/* See producer.h. */
|
||||
|
||||
@ -71,3 +72,147 @@ producer_is_gcc (const char *producer, int *major, int *minor)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* See producer.h. */
|
||||
|
||||
bool
|
||||
producer_is_icc (const char *producer, int *major, int *minor)
|
||||
{
|
||||
if (producer == NULL || !startswith (producer, "Intel(R)"))
|
||||
return false;
|
||||
|
||||
/* Prepare the used fields. */
|
||||
int maj, min;
|
||||
if (major == NULL)
|
||||
major = &maj;
|
||||
if (minor == NULL)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static bool warning_printed = false;
|
||||
/* Not recognized as Intel, let the user know. */
|
||||
if (!warning_printed)
|
||||
{
|
||||
warning (_("Could not recognize version of Intel Compiler in: \"%s\""),
|
||||
producer);
|
||||
warning_printed = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined GDB_SELF_TEST
|
||||
namespace selftests {
|
||||
namespace producer {
|
||||
|
||||
static void
|
||||
producer_parsing_tests ()
|
||||
{
|
||||
{
|
||||
/* Check that we don't crash if "Version" is not found in what
|
||||
looks like an ICC producer string. */
|
||||
static const char icc_no_version[] = "Intel(R) foo bar";
|
||||
|
||||
int major = 0, minor = 0;
|
||||
SELF_CHECK (!producer_is_icc (icc_no_version, &major, &minor));
|
||||
SELF_CHECK (!producer_is_gcc (icc_no_version, &major, &minor));
|
||||
}
|
||||
|
||||
{
|
||||
static const char extern_f_14_1[] = "\
|
||||
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));
|
||||
}
|
||||
|
||||
{
|
||||
static const char intern_f_14[] = "\
|
||||
Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on \
|
||||
Intel(R) 64, \
|
||||
Version 14.0";
|
||||
|
||||
int major = 0, minor = 0;
|
||||
SELF_CHECK (producer_is_icc (intern_f_14, &major, &minor)
|
||||
&& major == 14 && minor == 0);
|
||||
SELF_CHECK (!producer_is_gcc (intern_f_14, &major, &minor));
|
||||
}
|
||||
|
||||
{
|
||||
static const char intern_c_14[] = "\
|
||||
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on \
|
||||
Intel(R) 64, \
|
||||
Version 14.0";
|
||||
int major = 0, minor = 0;
|
||||
SELF_CHECK (producer_is_icc (intern_c_14, &major, &minor)
|
||||
&& major == 14 && minor == 0);
|
||||
SELF_CHECK (!producer_is_gcc (intern_c_14, &major, &minor));
|
||||
}
|
||||
|
||||
{
|
||||
static const char intern_c_18[] = "\
|
||||
Intel(R) C++ Intel(R) 64 Compiler for applications running on \
|
||||
Intel(R) 64, \
|
||||
Version 18.0 Beta";
|
||||
int major = 0, minor = 0;
|
||||
SELF_CHECK (producer_is_icc (intern_c_18, &major, &minor)
|
||||
&& major == 18 && minor == 0);
|
||||
}
|
||||
|
||||
{
|
||||
static const char gnu[] = "GNU C 4.7.2";
|
||||
SELF_CHECK (!producer_is_icc (gnu, NULL, NULL));
|
||||
|
||||
int major = 0, minor = 0;
|
||||
SELF_CHECK (producer_is_gcc (gnu, &major, &minor)
|
||||
&& major == 4 && minor == 7);
|
||||
}
|
||||
|
||||
{
|
||||
static const char gnu_exp[] = "GNU C++14 5.0.0 20150123 (experimental)";
|
||||
int major = 0, minor = 0;
|
||||
SELF_CHECK (!producer_is_icc (gnu_exp, NULL, NULL));
|
||||
SELF_CHECK (producer_is_gcc (gnu_exp, &major, &minor)
|
||||
&& major == 5 && minor == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_initialize_producer ()
|
||||
{
|
||||
#if defined GDB_SELF_TEST
|
||||
selftests::register_test
|
||||
("producer-parser", selftests::producer::producer_parsing_tests);
|
||||
#endif
|
||||
}
|
||||
|
@ -30,4 +30,26 @@ extern int producer_is_gcc_ge_4 (const char *producer);
|
||||
is NULL or it isn't GCC. */
|
||||
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 ....". */
|
||||
extern bool producer_is_icc (const char *producer, int *major, int *minor);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user