diff --git a/gcc/cobol/UAT/testsuite.src/syn_misc.at b/gcc/cobol/UAT/testsuite.src/syn_misc.at
index 28a10e25db1edfe19d81252ef79861b1ddb6d398..7a8956d18495e1c46bbfaa2eebba67c04c0f2fe6 100644
--- a/gcc/cobol/UAT/testsuite.src/syn_misc.at
+++ b/gcc/cobol/UAT/testsuite.src/syn_misc.at
@@ -480,7 +480,6 @@ AT_DATA([prog2.cob], [
 AT_CHECK([$COMPILE_ONLY prog.cob], [1], [],
 [prog.cob:7: ANY LENGTH valid only for 01 in LINKAGE SECTION of a contained program at 'LENGTH'
 prog.cob:9: 1 errors in DATA DIVISION, compilation ceases at 'PROCEDURE DIVISION'
-prog.cob:9: error: symbol 'str' not found
 cobol1: error: failed compiling prog.cob
 ])
 AT_CHECK([$COMPILE_ONLY prog2.cob], [1], [],
@@ -509,7 +508,6 @@ AT_DATA([prog.cob], [
 AT_CHECK([$COMPILE_ONLY prog.cob], [1], [],
 [prog.cob:7: ANY LENGTH valid only for 01 in LINKAGE SECTION of a contained program at 'LENGTH'
 prog.cob:9: 1 errors in DATA DIVISION, compilation ceases at 'PROCEDURE DIVISION'
-prog.cob:9: error: symbol 'str' not found
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
index bceb76bcf0dba644fcd4b413a5338257f62092c9..fe271bed0acdd67d2ffc3b3964c3050d1f40ae93 100644
--- a/gcc/cobol/symbols.cc
+++ b/gcc/cobol/symbols.cc
@@ -1656,7 +1656,10 @@ symbols_update( size_t first, bool parsed_ok ) {
 
     switch(field->level) {
     case 0:
-      if( field->is_key_name() ) continue;
+      if( field->is_key_name() ) {
+        update_symbol_map2(p);
+        continue;
+      }
       break;
     case 1:
       pend = calculate_capacity(p);
@@ -1746,6 +1749,7 @@ symbols_update( size_t first, bool parsed_ok ) {
     cbl_field_t *field = cbl_field_of(p);
     if( field->type == FldForward ) continue;
     if( field->type == FldSwitch ) continue;
+    if( field->level == 0 && field->is_key_name() ) continue;
     if( is_literal(field) && field->var_decl_node != NULL ) continue;
 
     if( field->is_typedef() ) {
@@ -1771,12 +1775,10 @@ symbols_update( size_t first, bool parsed_ok ) {
 
     assert( ! field->is_typedef() );
     
-    update_symbol_map2( p );
-    if( field->level == 0 && field->is_key_name() ) continue;
-    
     if( parsed_ok ) parser_symbol_add(field);
   }
 
+  finalize_symbol_map2();
   if( yydebug ) dump_symbol_map2();
   
   build_symbol_map();
@@ -2144,6 +2146,12 @@ symbol_table_init(void) {
   // Initialize symbol table.
   symbols = table;
 
+  for( auto e = symbols.elems; e < symbols.elems + symbols.nelem; e++ ) {
+    if( e->type == SymField ) {
+      update_symbol_map2(e);
+    }
+  }
+
   symbols.first_program = symbols.nelem;
 
   symbols.registers.linage_counter = symbol_index(symbol_field(0,0,
@@ -2425,6 +2433,8 @@ symbol_field_add( size_t program, struct cbl_field_t *field )
     numeric_constants[program][lname] = symbol_index(e);
   }
 
+  update_symbol_map2( e );
+
   return e;
 }
 
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index 3de3b73a67c8c31fe6a76fefca2191ac8f581899..f3c399e613b8ac2c7ff318dfab469033ed351ad7 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -1847,6 +1847,7 @@ void build_symbol_map();
 bool update_symbol_map( symbol_elem_t *e );
 
 void update_symbol_map2( const symbol_elem_t *elem );
+void finalize_symbol_map2();
 void dump_symbol_map2();
 
 std::pair<symbol_elem_t *, bool>
diff --git a/gcc/cobol/symfind.cc b/gcc/cobol/symfind.cc
index 022d66a24ef78e3f13c7213ebbfa8ff4be4899a2..5ecfbb0f641f7fa025351252b8f54b9d5f949dcf 100644
--- a/gcc/cobol/symfind.cc
+++ b/gcc/cobol/symfind.cc
@@ -97,13 +97,55 @@ static symbol_map_t symbol_map;
 typedef std::map <field_key_t, std::list<size_t> > field_keymap_t;
 static field_keymap_t symbol_map2;
 
+/*
+ * As each field is added to the symbol table, add its name and index
+ * to the name map.  Initially the type is FldInvalid.  Those are
+ * removed by symbols_update();
+ */
 void
 update_symbol_map2( const symbol_elem_t *e ) {
   auto field = cbl_field_of(e);
+  
+  if( ! field->is_typedef() ) {
+    switch( field->type ) {
+    case FldForward:
+    case FldLiteralN:
+      return;
+    case FldLiteralA:
+      if( ! field->is_key_name() ) return;
+      break;
+    default:
+      break;
+    }
+  }
+
   field_key_t fk( e->program, field );
   symbol_map2[fk].push_back(symbol_index(e));
 }
 
+/*
+ * Purge any field whose type is FldInvalid.  Remove any names that do
+ * not map to any field.
+ */
+void
+finalize_symbol_map2() {
+  std::set<field_key_t> empties;
+
+  for( auto& elem : symbol_map2 ) {
+    auto& fields( elem.second );
+    std::remove_if( fields.begin(), fields.end(),
+                  []( auto isym ) {
+                    auto f = cbl_field_of(symbol_at(isym));
+                    return f->type == FldInvalid;
+                  } );
+    if( fields.empty() ) empties.insert(elem.first);
+  }
+
+  for( const auto& key : empties ) {
+    symbol_map2.erase(key);
+  }
+}
+
 static void
 dump_symbol_map2( const field_key_t& key, const std::list<size_t>& candidates ) {
   if( !yydebug ) return;
@@ -128,7 +170,7 @@ dump_symbol_map2() {
   for( const auto& elem : symbol_map2 ) {
     const field_key_t& key( elem.first );
     const std::list<size_t>& candidates( elem.second);
-    if( key.program <= candidates.front() ) {
+    if( key.program != 0 ) {
       dump_symbol_map2( key, candidates );
       n++;
     }
@@ -425,10 +467,13 @@ symbol_match2( size_t program,
 
   field_key_t key(program, names.back());
 
-  for( auto candidate : symbol_map2[key] ) {
-    auto e = symbol_at(candidate);
-    if( name_has_names( e, names, local ) ) {
-      fields.push_back( symbol_index(e) );
+  auto plist = symbol_map2.find(key);
+  if( plist != symbol_map2.end() ) {
+    for( auto candidate : plist->second ) {
+      auto e = symbol_at(candidate);
+      if( name_has_names( e, names, local ) ) {
+        fields.push_back( symbol_index(e) );
+      }
     }
   }
 
@@ -439,7 +484,7 @@ symbol_match2( size_t program,
     }
   }
 
-  if( yydebug && ! fields.empty() ) {
+  if( yydebug ) {
     char *ancestry = NULL;
     const char *sep = "";
     for( auto name : names ) {
@@ -450,21 +495,26 @@ symbol_match2( size_t program,
       free(partial);
     }
 
-    char *fieldstr = NULL;
-    sep = "";
-    for( auto field : fields ) {
-      char *partial = fieldstr;
-      asprintf(&fieldstr, "%s%s%zu", partial? partial : "", sep, field);
-      sep = ", ";
-      assert(fieldstr);
-      free(partial);
-    }
+    if( fields.empty() ) {
+      warnx("%s: '%s' matches no fields", __func__, ancestry);
+      dump_symbol_map2();
+    } else {
+      char *fieldstr = NULL;
+      sep = "";
+      for( auto field : fields ) {
+        char *partial = fieldstr;
+        asprintf(&fieldstr, "%s%s%zu", partial? partial : "", sep, field);
+        sep = ", ";
+        assert(fieldstr);
+        free(partial);
+      }
 
-    warnx("%s: '%s' matches %zu fields: {%s}", __func__, ancestry, fields.size(), fieldstr);
+      warnx("%s: '%s' matches %zu fields: {%s}", __func__, ancestry, fields.size(), fieldstr);
+      free(fieldstr);
+    }
     free(ancestry);
-    free(fieldstr);
   }
-
+  
   return fields;
 }