+2019-05-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/90462
+ * diagnostic-format-json.cc: Include "selftest.h".
+ (json_from_expanded_location): Only add "file" key for non-NULL
+ file strings.
+ (json_from_location_range): Don't add "start" and "finish"
+ children if they are UNKNOWN_LOCATION.
+ (selftest::test_unknown_location): New selftest.
+ (selftest::test_bad_endpoints): New selftest.
+ (selftest::diagnostic_format_json_cc_tests): New function.
+ * json.cc (json::object::get): New function.
+ (selftest::test_object_get): New selftest.
+ (selftest::json_cc_tests): Call it.
+ * json.h (json::object::get): New decl.
+ * selftest-run-tests.c (selftest::run_tests): Call
+ selftest::diagnostic_format_json_cc_tests.
+ * selftest.h (selftest::diagnostic_format_json_cc_tests): New
+ decl.
+
2019-05-22 Kwok Cheung Yeung <kcy@codesourcery.com>
Andrew Stubbs <amd@codesourcery.com>
#include "coretypes.h"
#include "diagnostic.h"
#include "json.h"
+#include "selftest.h"
/* The top-level JSON array of pending diagnostics. */
{
expanded_location exploc = expand_location (loc);
json::object *result = new json::object ();
- result->set ("file", new json::string (exploc.file));
+ if (exploc.file)
+ result->set ("file", new json::string (exploc.file));
result->set ("line", new json::number (exploc.line));
result->set ("column", new json::number (exploc.column));
return result;
json::object *result = new json::object ();
result->set ("caret", json_from_expanded_location (caret_loc));
- if (start_loc != caret_loc)
+ if (start_loc != caret_loc
+ && start_loc != UNKNOWN_LOCATION)
result->set ("start", json_from_expanded_location (start_loc));
- if (finish_loc != caret_loc)
+ if (finish_loc != caret_loc
+ && finish_loc != UNKNOWN_LOCATION)
result->set ("finish", json_from_expanded_location (finish_loc));
if (loc_range->m_label)
break;
}
}
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* We shouldn't call json_from_expanded_location on UNKNOWN_LOCATION,
+ but verify that we handle this gracefully. */
+
+static void
+test_unknown_location ()
+{
+ delete json_from_expanded_location (UNKNOWN_LOCATION);
+}
+
+/* Verify that we gracefully handle attempts to serialize bad
+ compound locations. */
+
+static void
+test_bad_endpoints ()
+{
+ location_t bad_endpoints
+ = make_location (BUILTINS_LOCATION,
+ UNKNOWN_LOCATION, UNKNOWN_LOCATION);
+
+ location_range loc_range;
+ loc_range.m_loc = bad_endpoints;
+ loc_range.m_range_display_kind = SHOW_RANGE_WITH_CARET;
+ loc_range.m_label = NULL;
+
+ json::object *obj = json_from_location_range (&loc_range, 0);
+ /* We should have a "caret" value, but no "start" or "finish" values. */
+ ASSERT_TRUE (obj != NULL);
+ ASSERT_TRUE (obj->get ("caret") != NULL);
+ ASSERT_TRUE (obj->get ("start") == NULL);
+ ASSERT_TRUE (obj->get ("finish") == NULL);
+ delete obj;
+}
+
+/* Run all of the selftests within this file. */
+
+void
+diagnostic_format_json_cc_tests ()
+{
+ test_unknown_location ();
+ test_bad_endpoints ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
m_map.put (xstrdup (key), v);
}
+/* Get the json::value * for KEY.
+
+ The object retains ownership of the value. */
+
+value *
+object::get (const char *key) const
+{
+ gcc_assert (key);
+
+ value **ptr = const_cast <map_t &> (m_map).get (key);
+ if (ptr)
+ return *ptr;
+ else
+ return NULL;
+}
+
/* class json::array, a subclass of json::value, representing
an ordered collection of values. */
ASSERT_STREQ (expected_json, pp_formatted_text (&pp));
}
+/* Verify that object::get works as expected. */
+
+static void
+test_object_get ()
+{
+ object obj;
+ value *val = new json::string ("value");
+ obj.set ("foo", val);
+ ASSERT_EQ (obj.get ("foo"), val);
+ ASSERT_EQ (obj.get ("not-present"), NULL);
+}
+
/* Verify that JSON objects are written correctly. We can't test more than
one key/value pair, as we don't impose a guaranteed ordering. */
void
json_cc_tests ()
{
+ test_object_get ();
test_writing_objects ();
test_writing_arrays ();
test_writing_numbers ();
void print (pretty_printer *pp) const FINAL OVERRIDE;
void set (const char *key, value *v);
+ value *get (const char *key) const;
private:
typedef hash_map <char *, value *,
rely on. */
diagnostic_show_locus_c_tests ();
diagnostic_c_tests ();
+ diagnostic_format_json_cc_tests ();
edit_context_c_tests ();
fold_const_c_tests ();
spellcheck_c_tests ();
extern void cgraph_c_tests ();
extern void convert_c_tests ();
extern void diagnostic_c_tests ();
+extern void diagnostic_format_json_cc_tests ();
extern void diagnostic_show_locus_c_tests ();
extern void dumpfile_c_tests ();
extern void edit_context_c_tests ();
+2019-05-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/90462
+ * g++.dg/pr90462.C: New test.
+
2019-05-22 Marek Polacek <polacek@redhat.com>
* g++.dg/cpp1y/udlit-char-template-neg.C: Expect the error on a
--- /dev/null
+/* { dg-options "-Wdeprecated-copy -fdiagnostics-format=json" } */
+
+template <class> class b;
+struct B {
+ typedef b<char> *c;
+};
+class d {
+public:
+ B::c operator->();
+};
+template <class> struct e;
+class f {
+ typedef int g;
+};
+template <class, class> class h;
+template <class i> class b {
+public:
+ i j;
+ i k;
+ int l;
+ void assign() {
+ int m;
+ h<i, int> n(&m);
+ n.o(&j, &k, l);
+ }
+};
+template <class i, class> class s : f { s &p(const i *, const i *, g); };
+template <class i, class t> s<i, t> &s<i, t>::p(const i *, const i *, g) {
+ d q;
+ q->assign();
+}
+struct G {
+ G();
+ G(int);
+ G(G &);
+};
+template <class i, class> class h {
+public:
+ h(int *);
+ void o(const i *, const i *, unsigned);
+ i r();
+};
+template <class i, class t> void h<i, t>::o(const i *, const i *, unsigned) {
+ G a;
+ a = r();
+}
+template s<char, e<char>> &s<char, e<char>>::p(const char *, const char *, g);
+
+/* { dg-regexp ".*" } */