return block_iter_match_step (iterator, name, 0);
 }
 
+/* Return true if symbol A is the best match possible for DOMAIN.  */
+
+static bool
+best_symbol (struct symbol *a, const domain_enum domain)
+{
+  return (SYMBOL_DOMAIN (a) == domain
+         && SYMBOL_CLASS (a) != LOC_UNRESOLVED);
+}
+
+/* Return symbol B if it is a better match than symbol A for DOMAIN.
+   Otherwise return A.  */
+
+static struct symbol *
+better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain)
+{
+  if (a == NULL)
+    return b;
+  if (b == NULL)
+    return a;
+
+  if (SYMBOL_DOMAIN (a) == domain
+      && SYMBOL_DOMAIN (b) != domain)
+    return a;
+  if (SYMBOL_DOMAIN (b) == domain
+      && SYMBOL_DOMAIN (a) != domain)
+    return b;
+
+  if (SYMBOL_CLASS (a) != LOC_UNRESOLVED
+      && SYMBOL_CLASS (b) == LOC_UNRESOLVED)
+    return a;
+  if (SYMBOL_CLASS (b) != LOC_UNRESOLVED
+      && SYMBOL_CLASS (a) == LOC_UNRESOLVED)
+    return b;
+
+  return a;
+}
+
 /* See block.h.
 
    Note that if NAME is the demangled form of a C++ symbol, we will fail
 
       ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
        {
-         if (SYMBOL_DOMAIN (sym) == domain)
+         /* See comment related to PR gcc/debug/91507 in
+            block_lookup_symbol_primary.  */
+         if (best_symbol (sym, domain))
            return sym;
          /* This is a bit of a hack, but symbol_matches_domain might ignore
             STRUCT vs VAR domain symbols.  So if a matching symbol is found,
             exactly the same domain.  PR 16253.  */
          if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
                                     SYMBOL_DOMAIN (sym), domain))
-           other = sym;
+           other = better_symbol (other, sym, domain);
        }
       return other;
     }
        sym != NULL;
        sym = mdict_iter_match_next (lookup_name, &mdict_iter))
     {
-      if (SYMBOL_DOMAIN (sym) == domain)
+      /* With the fix for PR gcc/debug/91507, we get for:
+        ...
+        extern char *zzz[];
+        char *zzz[ ] = {
+          "abc",
+          "cde"
+        };
+        ...
+        DWARF which will result in two entries in the symbol table, a decl
+        with type char *[] and a def with type char *[2].
+
+        If we return the decl here, we don't get the value of zzz:
+        ...
+        $ gdb a.spec.out -batch -ex "p zzz"
+        $1 = 0x601030 <zzz>
+        ...
+        because we're returning the symbol without location information, and
+        because the fallback that uses the address from the minimal symbols
+        doesn't work either because the type of the decl does not specify a
+        size.
+
+        To fix this, we prefer def over decl in best_symbol and
+        better_symbol.
+
+        In absence of the gcc fix, both def and decl have type char *[], so
+        the only option to make this work is improve the fallback to use the
+        size of the minimal symbol.  Filed as PR exp/24989.  */
+      if (best_symbol (sym, domain))
        return sym;
 
       /* This is a bit of a hack, but symbol_matches_domain might ignore
         exactly the same domain.  PR 16253.  */
       if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
                                 SYMBOL_DOMAIN (sym), domain))
-       other = sym;
+       other = better_symbol (other, sym, domain);
     }
 
   return other;
 
                    var_b_label var_c_label var_p_label var_bad_label \
                    varval_label var_s_label var_untyped_label \
                    var_a_abstract_label var_a_concrete_label \
-                   varval2_label
+                   varval2_label varval3_def_label varval3_decl_label \
+                   int_array_label int_array_of_1_label
 
                set int_size [get_sizeof "int" -1]
 
                    {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr}
                }
 
+               int_array_label: DW_TAG_array_type {
+                   {DW_AT_type :${int_label}}
+               } {
+                   DW_TAG_subrange_type {}
+               }
+               varval3_decl_label: DW_TAG_variable {
+                   {DW_AT_name "varval3"}
+                   {DW_AT_type :${int_array_label}}
+                   {DW_AT_external 1 DW_FORM_flag}
+                   {DW_AT_declaration 1 DW_FORM_flag}
+               }
+               int_array_of_1_label: DW_TAG_array_type {
+                   {DW_AT_type :${int_label}}
+               } {
+                   DW_TAG_subrange_type {
+                       {DW_AT_type        :$int_label}
+                       {DW_AT_upper_bound 0 DW_FORM_data1}
+                   }
+               }
+               varval3_def_label: DW_TAG_variable {
+                   {DW_AT_name "varval3"}
+                   {DW_AT_external 1 DW_FORM_flag}
+                   {DW_AT_type :${int_array_of_1_label}}
+                   {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr}
+               }
+
                DW_TAG_subprogram {
                    {MACRO_AT_func { "main" "${srcdir}/${subdir}/${srcfile}" }}
                    {DW_AT_type :${int_label}}
     if [prepare_for_testing "failed to prepare" ${executable} [list ${asm_file} ${srcfile}] {}] {
        return -1
     }
-
-    # DW_OP_GNU_variable_value implementation requires a valid frame.
-    if ![runto_main] {
-       return -1
-    }
 }
 
 if { [setup_exec 0] == -1 } {
     return -1
 }
 
+with_test_prefix "pre-main" {
+    gdb_test "print varval3" "= \\{8\\}" ""
+}
+
+# DW_OP_GNU_variable_value implementation requires a valid frame.
+if ![runto_main] {
+    return -1
+}
+
 gdb_test "print varval" "= 8"
 gdb_test "print varval2" "= 8"
+gdb_test "print varval3" "= \\{8\\}"
 gdb_test "print constval" "= 53"
 gdb_test "print mixedval" "= 42"
 gdb_test "print pointerval" "= \\(int \\*\\) $hex <var_b>"
     return -1
 }
 
+# DW_OP_GNU_variable_value implementation requires a valid frame.
+if ![runto_main] {
+    return -1
+}
 gdb_test "print badval" "value has been optimized out"
 gdb_test "print bad_die_val1" \
          "invalid dwarf2 offset 0xabcdef11"