Commit dad2580c by David Malcolm Committed by David Malcolm

Fix segfault in -fsave-optimization-record (PR tree-optimization/86636)

There are various ways that it's possible for a gimple statement to
have an UNKNOWN_LOCATION, and for that UNKNOWN_LOCATION to be wrapped
in an ad-hoc location to capture inlining information.

For such a location, LOCATION_FILE (loc) is NULL.

Various places in -fsave-optimization-record were checking for
  loc != UNKNOWN_LOCATION
and were passing LOCATION_FILE (loc) to code that assumed a non-NULL
filename, thus leading to segfaults for the above cases.

This patch updates the tests to use
  LOCATION_LOCUS (loc) != UNKNOWN_LOCATION
instead, to look through ad-hoc location wrappers, fixing the segfaults.

It also adds various assertions to the affected code.

gcc/ChangeLog:
	PR tree-optimization/86636
	* json.cc (json::object::set): Fix comment.  Add assertions.
	(json::array::append): Move here from json.h.  Add comment and an
	assertion.
	(json::string::string): Likewise.
	* json.h (json::array::append): Move to json.cc.
	(json::string::string): Likewise.
	* optinfo-emit-json.cc
	(optrecord_json_writer::impl_location_to_json): Assert that we
	aren't attempting to write out UNKNOWN_LOCATION, or an ad-hoc
	wrapper around it.  Expand the location once, rather than three
	times.
	(optrecord_json_writer::inlining_chain_to_json): Fix the check for
	UNKNOWN_LOCATION, to use LOCATION_LOCUS to look through ad-hoc
	wrappers.
	(optrecord_json_writer::optinfo_to_json): Likewise, in four
	places.  Fix some overlong lines.

gcc/testsuite/ChangeLog:
	PR tree-optimization/86636
	* gcc.c-torture/compile/pr86636.c: New test.

From-SVN: r262950
parent 8da03df5
2018-07-24 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/86636
* json.cc (json::object::set): Fix comment. Add assertions.
(json::array::append): Move here from json.h. Add comment and an
assertion.
(json::string::string): Likewise.
* json.h (json::array::append): Move to json.cc.
(json::string::string): Likewise.
* optinfo-emit-json.cc
(optrecord_json_writer::impl_location_to_json): Assert that we
aren't attempting to write out UNKNOWN_LOCATION, or an ad-hoc
wrapper around it. Expand the location once, rather than three
times.
(optrecord_json_writer::inlining_chain_to_json): Fix the check for
UNKNOWN_LOCATION, to use LOCATION_LOCUS to look through ad-hoc
wrappers.
(optrecord_json_writer::optinfo_to_json): Likewise, in four
places. Fix some overlong lines.
2018-07-24 Matthew Malcomson <matthew.malcomson@arm.com> 2018-07-24 Matthew Malcomson <matthew.malcomson@arm.com>
* config/aarch64/aarch64-simd.md * config/aarch64/aarch64-simd.md
......
...@@ -76,12 +76,15 @@ object::print (pretty_printer *pp) const ...@@ -76,12 +76,15 @@ object::print (pretty_printer *pp) const
pp_character (pp, '}'); pp_character (pp, '}');
} }
/* Set the json::value * for KEY, taking ownership of VALUE /* Set the json::value * for KEY, taking ownership of V
(and taking a copy of KEY if necessary). */ (and taking a copy of KEY if necessary). */
void void
object::set (const char *key, value *v) object::set (const char *key, value *v)
{ {
gcc_assert (key);
gcc_assert (v);
value **ptr = m_map.get (key); value **ptr = m_map.get (key);
if (ptr) if (ptr)
{ {
...@@ -126,6 +129,15 @@ array::print (pretty_printer *pp) const ...@@ -126,6 +129,15 @@ array::print (pretty_printer *pp) const
pp_character (pp, ']'); pp_character (pp, ']');
} }
/* Append non-NULL value V to a json::array, taking ownership of V. */
void
array::append (value *v)
{
gcc_assert (v);
m_elements.safe_push (v);
}
/* class json::number, a subclass of json::value, wrapping a double. */ /* class json::number, a subclass of json::value, wrapping a double. */
/* Implementation of json::value::print for json::number. */ /* Implementation of json::value::print for json::number. */
...@@ -140,6 +152,16 @@ number::print (pretty_printer *pp) const ...@@ -140,6 +152,16 @@ number::print (pretty_printer *pp) const
/* class json::string, a subclass of json::value. */ /* class json::string, a subclass of json::value. */
/* json::string's ctor. */
string::string (const char *utf8)
{
gcc_assert (utf8);
m_utf8 = xstrdup (utf8);
}
/* Implementation of json::value::print for json::string. */
void void
string::print (pretty_printer *pp) const string::print (pretty_printer *pp) const
{ {
......
...@@ -107,7 +107,7 @@ class array : public value ...@@ -107,7 +107,7 @@ class array : public value
enum kind get_kind () const FINAL OVERRIDE { return JSON_ARRAY; } enum kind get_kind () const FINAL OVERRIDE { return JSON_ARRAY; }
void print (pretty_printer *pp) const FINAL OVERRIDE; void print (pretty_printer *pp) const FINAL OVERRIDE;
void append (value *v) { m_elements.safe_push (v); } void append (value *v);
private: private:
auto_vec<value *> m_elements; auto_vec<value *> m_elements;
...@@ -134,7 +134,7 @@ class number : public value ...@@ -134,7 +134,7 @@ class number : public value
class string : public value class string : public value
{ {
public: public:
string (const char *utf8) : m_utf8 (xstrdup (utf8)) {} string (const char *utf8);
~string () { free (m_utf8); } ~string () { free (m_utf8); }
enum kind get_kind () const FINAL OVERRIDE { return JSON_STRING; } enum kind get_kind () const FINAL OVERRIDE { return JSON_STRING; }
......
...@@ -202,10 +202,12 @@ optrecord_json_writer::impl_location_to_json (dump_impl_location_t loc) ...@@ -202,10 +202,12 @@ optrecord_json_writer::impl_location_to_json (dump_impl_location_t loc)
json::object * json::object *
optrecord_json_writer::location_to_json (location_t loc) optrecord_json_writer::location_to_json (location_t loc)
{ {
gcc_assert (LOCATION_LOCUS (loc) != UNKNOWN_LOCATION);
expanded_location exploc = expand_location (loc);
json::object *obj = new json::object (); json::object *obj = new json::object ();
obj->set ("file", new json::string (LOCATION_FILE (loc))); obj->set ("file", new json::string (exploc.file));
obj->set ("line", new json::number (LOCATION_LINE (loc))); obj->set ("line", new json::number (exploc.line));
obj->set ("column", new json::number (LOCATION_COLUMN (loc))); obj->set ("column", new json::number (exploc.column));
return obj; return obj;
} }
...@@ -330,7 +332,7 @@ optrecord_json_writer::inlining_chain_to_json (location_t loc) ...@@ -330,7 +332,7 @@ optrecord_json_writer::inlining_chain_to_json (location_t loc)
const char *printable_name const char *printable_name
= lang_hooks.decl_printable_name (fndecl, 2); = lang_hooks.decl_printable_name (fndecl, 2);
obj->set ("fndecl", new json::string (printable_name)); obj->set ("fndecl", new json::string (printable_name));
if (*locus != UNKNOWN_LOCATION) if (LOCATION_LOCUS (*locus) != UNKNOWN_LOCATION)
obj->set ("site", location_to_json (*locus)); obj->set ("site", location_to_json (*locus));
array->append (obj); array->append (obj);
} }
...@@ -371,8 +373,9 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo) ...@@ -371,8 +373,9 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo)
json_item->set ("expr", new json::string (item->get_text ())); json_item->set ("expr", new json::string (item->get_text ()));
/* Capture any location for the node. */ /* Capture any location for the node. */
if (item->get_location () != UNKNOWN_LOCATION) if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
json_item->set ("location", location_to_json (item->get_location ())); json_item->set ("location",
location_to_json (item->get_location ()));
message->append (json_item); message->append (json_item);
} }
...@@ -383,8 +386,9 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo) ...@@ -383,8 +386,9 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo)
json_item->set ("stmt", new json::string (item->get_text ())); json_item->set ("stmt", new json::string (item->get_text ()));
/* Capture any location for the stmt. */ /* Capture any location for the stmt. */
if (item->get_location () != UNKNOWN_LOCATION) if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
json_item->set ("location", location_to_json (item->get_location ())); json_item->set ("location",
location_to_json (item->get_location ()));
message->append (json_item); message->append (json_item);
} }
...@@ -395,8 +399,9 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo) ...@@ -395,8 +399,9 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo)
json_item->set ("symtab_node", new json::string (item->get_text ())); json_item->set ("symtab_node", new json::string (item->get_text ()));
/* Capture any location for the node. */ /* Capture any location for the node. */
if (item->get_location () != UNKNOWN_LOCATION) if (LOCATION_LOCUS (item->get_location ()) != UNKNOWN_LOCATION)
json_item->set ("location", location_to_json (item->get_location ())); json_item->set ("location",
location_to_json (item->get_location ()));
message->append (json_item); message->append (json_item);
} }
break; break;
......
2018-07-24 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/86636
* gcc.c-torture/compile/pr86636.c: New test.
2018-07-24 Matthew Malcomson <matthew.malcomson@arm.com> 2018-07-24 Matthew Malcomson <matthew.malcomson@arm.com>
* gcc.target/aarch64/vect-su-add-sub.c: New. * gcc.target/aarch64/vect-su-add-sub.c: New.
......
/* { dg-options "-fsave-optimization-record -ftree-loop-vectorize -ftree-parallelize-loops=2" } */
void
n2 (int ih)
{
while (ih < 1)
++ih;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment