From 93657b33b0266d4c82f01d6cdc203f0374a2cd99 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 2 Nov 2018 11:34:39 -0400
Subject: [PATCH 15/21] FIXME: add gcc/testsuite/g++.dg/init/pr43064-4.C; WIP
 on fixing it

---
 gcc/cp/parser.c                       | 35 ++++++++++++++++++++++++++++++-----
 gcc/testsuite/g++.dg/init/pr43064-4.C | 18 ++++++++++++++++++
 2 files changed, 48 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/init/pr43064-4.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8b0bd2b..b74272b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2304,7 +2304,7 @@ static void cp_parser_ctor_initializer_opt
   (cp_parser *);
 static void cp_parser_mem_initializer_list
   (cp_parser *);
-static tree cp_parser_mem_initializer
+static cp_expr cp_parser_mem_initializer
   (cp_parser *);
 static tree cp_parser_mem_initializer_id
   (cp_parser *);
@@ -14820,14 +14820,21 @@ cp_parser_mem_initializer_list (cp_parser* parser)
     error_at (token->location,
 	      "only constructors take member initializers");
 
+  auto_vec<location_t> mem_initializer_locs;
+
   /* Loop through the list.  */
   while (true)
     {
-      tree mem_initializer;
+      cp_expr mem_initializer;
 
       token = cp_lexer_peek_token (parser->lexer);
       /* Parse the mem-initializer.  */
       mem_initializer = cp_parser_mem_initializer (parser);
+      mem_initializer_locs.safe_push (mem_initializer.get_location ());
+
+      // FIXME:
+      //inform (mem_initializer.get_location (), "mem-initializer");
+
       /* If the next token is a `...', we're expanding member initializers. */
       bool ellipsis = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
       if (ellipsis
@@ -14890,7 +14897,7 @@ cp_parser_mem_initializer_list (cp_parser* parser)
 
   /* Perform semantic analysis.  */
   if (DECL_CONSTRUCTOR_P (current_function_decl))
-    finish_mem_initializers (mem_initializer_list);
+    finish_mem_initializers (mem_initializer_list/*, &mem_initializer_locs*/);
 }
 
 /* Parse a mem-initializer.
@@ -14909,13 +14916,15 @@ cp_parser_mem_initializer_list (cp_parser* parser)
    the TREE_VALUE is the expression-list.  An empty initialization
    list is represented by void_list_node.  */
 
-static tree
+static cp_expr
 cp_parser_mem_initializer (cp_parser* parser)
 {
   tree mem_initializer_id;
   tree expression_list;
   tree member;
   cp_token *token = cp_lexer_peek_token (parser->lexer);
+  location_t start_loc = token->location;
+  location_t caret_loc = UNKNOWN_LOCATION;
 
   /* Find out what is being initialized.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -14923,6 +14932,7 @@ cp_parser_mem_initializer (cp_parser* parser)
       permerror (token->location,
 		 "anachronistic old-style base class initializer");
       mem_initializer_id = NULL_TREE;
+      caret_loc = start_loc;
     }
   else
     {
@@ -14934,6 +14944,10 @@ cp_parser_mem_initializer (cp_parser* parser)
   if (member && !DECL_P (member))
     in_base_initializer = 1;
 
+  token = cp_lexer_peek_token (parser->lexer);
+  if (token)
+    caret_loc = token->location;
+
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
       bool expr_non_constant_p;
@@ -14965,7 +14979,18 @@ cp_parser_mem_initializer (cp_parser* parser)
 
   in_base_initializer = 0;
 
-  return member ? build_tree_list (member, expression_list) : error_mark_node;
+  if (!member)
+    return error_mark_node;
+
+  /* Generate a location of the form:
+        m_fieldname (arg0, arg1),
+        ~~~~~~~~~~~~^~~~~~~~~~~~
+  */    
+  location_t finish_loc
+    = get_finish (cp_lexer_previous_token (parser->lexer)->location);
+  location_t combined_loc = make_location (caret_loc, start_loc, finish_loc);
+
+  return cp_expr (build_tree_list (member, expression_list), combined_loc);
 }
 
 /* Parse a mem-initializer-id.
diff --git a/gcc/testsuite/g++.dg/init/pr43064-4.C b/gcc/testsuite/g++.dg/init/pr43064-4.C
new file mode 100644
index 0000000..830ddf6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pr43064-4.C
@@ -0,0 +1,18 @@
+// { dg-do compile }
+// { dg-options "-fdiagnostics-show-caret" }
+
+class A {};
+class B {};
+
+struct t1
+{
+  A m_a;
+  int m_int;
+
+  /* The type mismatch for the member initializer for "m_a" should be
+     reported there, rather than on the final token (for "m_int").  */
+  t1(B b)
+    : m_a (b),
+      m_int (42)
+  {}
+};
-- 
1.8.5.3

