diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 5102470..05c92ac 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -558,6 +558,11 @@ function_method:       exp '(' parameter_typelist ')' const_or_volatile
 			  LONGEST len = VEC_length (type_ptr, type_list);
 
 			  write_exp_elt_opcode (pstate, TYPE_INSTANCE);
+			  /* Save the const/volatile qualifiers as
+			     recorded by the const_or_volatile
+			     production's actions.  */
+			  write_exp_elt_longcst (pstate,
+						 follow_type_instance_flags ());
 			  write_exp_elt_longcst (pstate, len);
 			  for (i = 0;
 			       VEC_iterate (type_ptr, type_list, i, type_elt);
@@ -571,6 +576,9 @@ function_method:       exp '(' parameter_typelist ')' const_or_volatile
 
 function_method_void:	    exp '(' ')' const_or_volatile
 		       { write_exp_elt_opcode (pstate, TYPE_INSTANCE);
+			 /* See above.  */
+			 write_exp_elt_longcst (pstate,
+						follow_type_instance_flags ());
 			 write_exp_elt_longcst (pstate, 0);
 			 write_exp_elt_longcst (pstate, 0);
 			 write_exp_elt_opcode (pstate, TYPE_INSTANCE);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 6845fd7..108296d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -7947,6 +7947,23 @@ free_delayed_list (void *ptr)
     }
 }
 
+/* Check whether [PHYSNAME, PHYSNAME+LEN) ends with a modifier like
+   "const" / "volatile".  If so, decrements LEN by the length of the
+   modifier and return true.  Otherwise return false.  */
+
+template<size_t N>
+static bool
+check_modifier (const char *physname, size_t &len, const char (&mod)[N])
+{
+  size_t mod_len = sizeof (mod) - 1;
+  if (len > mod_len && startswith (physname + (len - mod_len), mod))
+    {
+      len -= mod_len;
+      return true;
+    }
+  return false;
+}
+
 /* Compute the physnames of any methods on the CU's method list.
 
    The computation of method physnames is delayed in order to avoid the
@@ -7958,6 +7975,12 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
 {
   int i;
   struct delayed_method_info *mi;
+
+  /* Only C++ delays computing physnames.  */
+  if (VEC_empty (delayed_method_info, cu->method_list))
+    return;
+  gdb_assert (cu->language == language_cplus);
+
   for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
     {
       const char *physname;
@@ -7966,6 +7989,26 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
       physname = dwarf2_physname (mi->name, mi->die, cu);
       TYPE_FN_FIELD_PHYSNAME (fn_flp->fn_fields, mi->index)
 	= physname ? physname : "";
+
+      /* Since there's no tag to indicate whether a method is a
+	 const/volatile overload, extract that information out of the
+	 demangled name.  */
+      if (physname != NULL)
+	{
+	  size_t len = strlen (physname);
+
+	  while (1)
+	    {
+	      if (physname[len] == ')') /* shortcut */
+		break;
+	      else if (check_modifier (physname, len, " const"))
+		TYPE_FN_FIELD_CONST (fn_flp->fn_fields, mi->index) = 1;
+	      else if (check_modifier (physname, len, " volatile"))
+		TYPE_FN_FIELD_VOLATILE (fn_flp->fn_fields, mi->index) = 1;
+	      else
+		break;
+	    }
+	}
     }
 }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 7d129f0..5a434b9 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -642,18 +642,22 @@ ptrmath_type_p (const struct language_defn *lang, struct type *type)
     }
 }
 
-/* Constructs a fake method with the given parameter types.
-   This function is used by the parser to construct an "expected"
-   type for method overload resolution.  */
+/* Constructs a fake method with the given parameter types.  This
+   function is used by the parser to construct an "expected" type for
+   method overload resolution.  FLAGS is used as instance flags of the
+   new type, in order to be able to make the new type represent a
+   const/volatile overload.  */
 
 static struct type *
-make_params (int num_types, struct type **param_types)
+make_params (type_instance_flags flags,
+	     int num_types, struct type **param_types)
 {
   struct type *type = XCNEW (struct type);
   TYPE_MAIN_TYPE (type) = XCNEW (struct main_type);
   TYPE_LENGTH (type) = 1;
   TYPE_CODE (type) = TYPE_CODE_METHOD;
   TYPE_CHAIN (type) = type;
+  TYPE_INSTANCE_FLAGS (type) = flags;
   if (num_types > 0)
     {
       if (param_types[num_types - 1] == NULL)
@@ -2039,18 +2043,22 @@ evaluate_subexp_standard (struct type *expect_type,
 	}
 
     case TYPE_INSTANCE:
-      nargs = longest_to_int (exp->elts[pc + 1].longconst);
-      arg_types = (struct type **) alloca (nargs * sizeof (struct type *));
-      for (ix = 0; ix < nargs; ++ix)
-	arg_types[ix] = exp->elts[pc + 1 + ix + 1].type;
-
-      expect_type = make_params (nargs, arg_types);
-      *(pos) += 3 + nargs;
-      arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
-      xfree (TYPE_FIELDS (expect_type));
-      xfree (TYPE_MAIN_TYPE (expect_type));
-      xfree (expect_type);
-      return arg1;
+      {
+	type_instance_flags flags
+	  = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst);
+	nargs = longest_to_int (exp->elts[pc + 2].longconst);
+	arg_types = (struct type **) alloca (nargs * sizeof (struct type *));
+	for (ix = 0; ix < nargs; ++ix)
+	  arg_types[ix] = exp->elts[pc + 2 + ix + 1].type;
+
+	expect_type = make_params (flags, nargs, arg_types);
+	*(pos) += 4 + nargs;
+	arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
+	xfree (TYPE_FIELDS (expect_type));
+	xfree (TYPE_MAIN_TYPE (expect_type));
+	xfree (expect_type);
+	return arg1;
+      }
 
     case BINOP_CONCAT:
       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
diff --git a/gdb/expprint.c b/gdb/expprint.c
index fad20e8..2c16b49 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -543,11 +543,15 @@ print_subexp_standard (struct expression *exp, int *pos,
 
     case TYPE_INSTANCE:
       {
-	LONGEST count = exp->elts[pc + 1].longconst;
+	type_instance_flags flags
+	  = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst);
+	LONGEST count = exp->elts[pc + 2].longconst;
 
+	/* The FLAGS.  */
+	(*pos)++;
 	/* The COUNT.  */
 	(*pos)++;
-	fputs_unfiltered ("TypesInstance(", stream);
+	fputs_unfiltered ("TypeInstance(", stream);
 	while (count-- > 0)
 	  {
 	    type_print (exp->elts[(*pos)++].type, "", stream, 0);
@@ -558,6 +562,12 @@ print_subexp_standard (struct expression *exp, int *pos,
 	/* Ending COUNT and ending TYPE_INSTANCE.  */
 	(*pos) += 2;
 	print_subexp (exp, pos, stream, PREC_PREFIX);
+
+	if (flags & TYPE_INSTANCE_FLAG_CONST)
+	  fputs_unfiltered (",const", stream);
+	if (flags & TYPE_INSTANCE_FLAG_VOLATILE)
+	  fputs_unfiltered (",volatile", stream);
+
 	fputs_unfiltered (")", stream);
 	return;
       }
@@ -1019,9 +1029,9 @@ dump_subexp_body_standard (struct expression *exp,
 
     case TYPE_INSTANCE:
       {
-	LONGEST len;
-
-	len = exp->elts[elt++].longconst;
+	type_instance_flags flags
+	  = (type_instance_flag_value) longest_to_int (exp->elts[elt++].longconst);
+	LONGEST len = exp->elts[elt++].longconst;
 	fprintf_filtered (stream, "%s TypeInstance: ", plongest (len));
 	while (len-- > 0)
 	  {
@@ -1034,6 +1044,22 @@ dump_subexp_body_standard (struct expression *exp,
 	    if (len > 0)
 	      fputs_filtered (", ", stream);
 	  }
+
+	fprintf_filtered (stream, " Flags: %s (", hex_string (flags));
+	bool space = false;
+	auto print_one = [&] (const char *mod)
+	  {
+	    if (space)
+	      fputs_filtered (" ", stream);
+	    space = true;
+	    fprintf_filtered (stream, mod);
+	  };
+	if (flags & TYPE_INSTANCE_FLAG_CONST)
+	  print_one ("const");
+	if (flags & TYPE_INSTANCE_FLAG_VOLATILE)
+	  print_one ("volatile");
+	fprintf_filtered (stream, ")");
+
 	/* Ending LEN and ending TYPE_INSTANCE.  */
 	elt += 2;
 	elt = dump_subexp (exp, stream, elt);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index d2018a8..9d9b09f 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -46,6 +46,7 @@
 
 #include "hashtab.h"
 #include "common/offset-type.h"
+#include "common/enum-flags.h"
 
 /* Forward declarations for prototypes.  */
 struct field;
@@ -196,6 +197,8 @@ enum type_instance_flag_value
   TYPE_INSTANCE_FLAG_ATOMIC = (1 << 8)
 };
 
+DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags);
+
 /* * Unsigned integer type.  If this is not set for a TYPE_CODE_INT,
    the type is signed (unless TYPE_NOSIGN (below) is set).  */
 
@@ -304,25 +307,25 @@ enum type_instance_flag_value
 /* * Constant type.  If this is set, the corresponding type has a
    const modifier.  */
 
-#define TYPE_CONST(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_CONST)
+#define TYPE_CONST(t) ((TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_CONST) != 0)
 
 /* * Volatile type.  If this is set, the corresponding type has a
    volatile modifier.  */
 
 #define TYPE_VOLATILE(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_VOLATILE)
+  ((TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_VOLATILE) != 0)
 
 /* * Restrict type.  If this is set, the corresponding type has a
    restrict modifier.  */
 
 #define TYPE_RESTRICT(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_RESTRICT)
+  ((TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_RESTRICT) != 0)
 
 /* * Atomic type.  If this is set, the corresponding type has an
    _Atomic modifier.  */
 
 #define TYPE_ATOMIC(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
+  ((TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC) != 0)
 
 /* * True if this type represents either an lvalue or lvalue reference type.  */
 
@@ -349,10 +352,10 @@ enum type_instance_flag_value
    is instruction space, and for data objects is data memory.  */
 
 #define TYPE_CODE_SPACE(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_CODE_SPACE)
+  ((TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_CODE_SPACE) != 0)
 
 #define TYPE_DATA_SPACE(t) \
-  (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_DATA_SPACE)
+  ((TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_DATA_SPACE) != 0)
 
 /* * Address class flags.  Some environments provide for pointers
    whose size is different from that of a normal pointer or address
diff --git a/gdb/parse.c b/gdb/parse.c
index 97ddc72..6f85eba 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -926,7 +926,7 @@ operator_length_standard (const struct expression *expr, int endpos,
       break;
 
     case TYPE_INSTANCE:
-      oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = 5 + longest_to_int (expr->elts[endpos - 2].longconst);
       args = 1;
       break;
 
@@ -1646,6 +1646,33 @@ push_typelist (VEC (type_ptr) *list)
   push_type (tp_function_with_arguments);
 }
 
+/* Pop the type stack and return a type_instance_flags that
+   corresponds the const/volatile qualifiers on the stack.  This is
+   called by the C++ parser when parsing methods types, and as such no
+   other kind of type in the type stack is expected.  */
+
+type_instance_flags
+follow_type_instance_flags ()
+{
+  type_instance_flags flags = 0;
+
+  for (;;)
+    switch (pop_type ())
+      {
+      case tp_end:
+	return flags;
+      case tp_const:
+	flags |= TYPE_INSTANCE_FLAG_CONST;
+	break;
+      case tp_volatile:
+	flags |= TYPE_INSTANCE_FLAG_VOLATILE;
+	break;
+      default:
+	gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
+      }
+}
+
+
 /* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
    as modified by all the stuff on the stack.  */
 struct type *
@@ -1825,11 +1852,11 @@ operator_check_standard (struct expression *exp, int pos,
 
     case TYPE_INSTANCE:
       {
-	LONGEST arg, nargs = elts[pos + 1].longconst;
+	LONGEST arg, nargs = elts[pos + 2].longconst;
 
 	for (arg = 0; arg < nargs; arg++)
 	  {
-	    struct type *type = elts[pos + 2 + arg].type;
+	    struct type *type = elts[pos + 3 + arg].type;
 	    struct objfile *objfile = TYPE_OBJFILE (type);
 
 	    if (objfile && (*objfile_func) (objfile, data))
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index fadc2ef..f7ba7f0 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -266,6 +266,8 @@ extern const char *op_name_standard (enum exp_opcode);
 
 extern struct type *follow_types (struct type *);
 
+extern type_instance_flags follow_type_instance_flags ();
+
 extern void null_post_parser (struct expression **, int);
 
 extern int parse_float (const char *p, int len, DOUBLEST *d,
diff --git a/gdb/testsuite/gdb.cp/local-static.c b/gdb/testsuite/gdb.cp/local-static.c
index 5bfff8d..0f4c4f0 100644
--- a/gdb/testsuite/gdb.cp/local-static.c
+++ b/gdb/testsuite/gdb.cp/local-static.c
@@ -53,10 +53,17 @@ struct S
   }
 
   void method ();
+  void method () const;
+  void method () volatile;
+  void method () volatile const;
+
   static void static_method ();
 };
 
 S s;
+const S c_s = {};
+volatile S v_s = {};
+const volatile S cv_s = {};
 
 void
 S::method ()
@@ -65,6 +72,24 @@ S::method ()
 }
 
 void
+S::method () const
+{
+  DEF_STATICS (S_M_C);
+}
+
+void
+S::method () volatile
+{
+  DEF_STATICS (S_M_V);
+}
+
+void
+S::method () const volatile
+{
+  DEF_STATICS (S_M_CV);
+}
+
+void
 S::static_method ()
 {
   DEF_STATICS (S_SM);
@@ -127,6 +152,9 @@ main ()
 
 #ifdef __cplusplus
       s.method ();
+      c_s.method ();
+      v_s.method ();
+      cv_s.method ();
       s.inline_method ();
       S::static_method ();
       S::static_inline_method ();
diff --git a/gdb/testsuite/gdb.cp/local-static.exp b/gdb/testsuite/gdb.cp/local-static.exp
index 581efa3..5e8eaaa 100644
--- a/gdb/testsuite/gdb.cp/local-static.exp
+++ b/gdb/testsuite/gdb.cp/local-static.exp
@@ -19,28 +19,98 @@
 
 standard_testfile .c
 
+# A few expected errors.
+set syntax_re "A syntax error in expression, near.*"
+set cannot_resolve_re "Cannot resolve method S::method to any overloaded instance"
+
+# Build an "Cannot resolve method ..." expected error string for
+# method METH.
+#
+proc cannot_resolve {meth} {
+    return "Cannot resolve method $meth to any overloaded instance"
+}
+
 # A list of scopes that have the static variables that we want to
 # print.  Each entry has, in order, the scope/function name, and the
-# prefix used by the static variables.  (The prefix exists to make it
-# easier to debug the test if something goes wrong.)
-
-     #SCOPE				#PREFIX
+# prefix used by the static variables.  The prefix exists both to make
+# it easier to debug the test if something goes wrong, and, to make
+# sure that printing the static local of one method overload doesn't
+# find the variables of the wrong overload.
+#
+# While at it, we also try printing each scope without the static
+# local, to check that the parse copes with cv overloads without
+# quoting.  That's what the third and forth columns are for.  Note
+# that printing "func()" is different from "func(void)".  The former
+# is an inferior function call, while the latter is a reference to the
+# function.
+
+     #SCOPE				#PREFIX         #PRINT-SCOPE-QUOTED
+							#PRINT-SCOPE-UNQUOTED (opt)
 set cxx_scopes_list {
-    {"S::method()"			"S_M"}
-    {"S::static_method()"		"S_SM"}
-    {"S::inline_method()"		"S_IM"}
-    {"S::static_inline_method()"	"S_SIM"}
-    {"S2<int>::method()"		"S2_M"}
-    {"S2<int>::static_method()"		"S2_SM"}
-    {"S2<int>::inline_method()"		"S2_IM"}
-    {"S2<int>::static_inline_method()"	"S2_SIM"}
-    {"free_func()"			"FF"}
-    {"free_inline_func()"		"FIF"}
+    {"S::method()"			"S_M"		{= \\{void \\(S \\* const\\)\\} $hex <S::method\\(\\)>}
+							{[cannot_resolve "S::method"]}}
+
+    {"S::method() const"		"S_M_C"		{= \\{void \\(const S \\* const\\)\\} $hex <S::method\\(\\) const>}
+							$syntax_re}
+
+    {"S::method() volatile"		"S_M_V"		{= \\{void \\(volatile S \\* const\\)\\} $hex <S::method\\(\\) volatile>}
+							$syntax_re}
+
+    {"S::method() const volatile"	"S_M_CV"	{= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}
+							$syntax_re}
+
+    {"S::method() volatile const"	"S_M_CV"	{= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}
+							$syntax_re}
+
+    {"S::method(void)"			"S_M"		{= \\{void \\(S \\* const\\)\\} $hex <S::method\\(\\)>}}
+    {"S::method(void) const"		"S_M_C"		{= \\{void \\(const S \\* const\\)\\} $hex <S::method\\(\\) const>}}
+    {"S::method(void) volatile"		"S_M_V"		{= \\{void \\(volatile S \\* const\\)\\} $hex <S::method\\(\\) volatile>}}
+    {"S::method(void) const volatile"	"S_M_CV"	{= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}}
+    {"S::method(void) volatile const"	"S_M_CV"	{= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}}
+
+    {"S::static_method()"		"S_SM"		{= \\{void \\(void\\)\\} $hex <S::static_method\\(\\)>}
+							"void"}
+
+    {"S::static_method(void)"		"S_SM"		{= \\{void \\(void\\)\\} $hex <S::static_method\\(\\)>}}
+
+    {"S::inline_method()"		"S_IM"		{= \\{void \\(S \\* const\\)\\} $hex <S::inline_method\\(\\)>}
+							{[cannot_resolve "S::inline_method"]}}
+
+    {"S::inline_method(void)"		"S_IM"		{= \\{void \\(S \\* const\\)\\} $hex <S::inline_method\\(\\)>}}
+
+    {"S::static_inline_method()"	"S_SIM"		{= \\{void \\(void\\)\\} $hex <S::static_inline_method\\(\\)>}
+							"void"}
+
+    {"S::static_inline_method(void)"	"S_SIM"		{= \\{void \\(void\\)\\} $hex <S::static_inline_method\\(\\)>}}
+
+    {"S2<int>::method()"		"S2_M"		{= \\{void \\(S2<int> \\* const\\)\\} $hex <S2<int>::method\\(\\)>}
+							{[cannot_resolve "S2<int>::method"]}}
+
+    {"S2<int>::static_method()"		"S2_SM"		{= \\{void \\(void\\)\\} $hex <S2<int>::static_method\\(\\)>}
+							"void"}
+
+    {"S2<int>::inline_method()"		"S2_IM"		{= \\{void \\(S2<int> \\* const\\)\\} $hex <S2<int>::inline_method\\(\\)>}
+							{[cannot_resolve "S2<int>::inline_method"]}}
+
+    {"S2<int>::static_inline_method()"	"S2_SIM"	{= \\{void \\(void\\)\\} $hex <S2<int>::static_inline_method\\(\\)>}
+							"void"}
+
+    {"free_func"			"FF"		{= \\{void \\(void\\)\\} $hex <free_func\\(\\)>}}
+
+    {"free_func()"			"FF"		{= \\{void \\(void\\)\\} $hex <free_func\\(\\)>}
+							"void"}
+
+    {"free_func(void)"			"FF"		{= \\{void \\(void\\)\\} $hex <free_func\\(\\)>}}
+
+    {"free_inline_func()"		"FIF"		{= \\{void \\(void\\)\\} $hex <free_inline_func\\(\\)>}
+							"void"}
+
+    {"free_inline_func(void)"		"FIF"		{= \\{void \\(void\\)\\} $hex <free_inline_func\\(\\)>}}
 }
 
 set c_scopes_list {
-    {"free_func"			"FF"}
-    {"free_inline_func"			"FIF"}
+    {"free_func"			"FF"		{= \\{void \\(void\\)\\} $hex <free_func>}}
+    {"free_inline_func"			"FIF"		{= \\{void \\(void\\)\\} $hex <free_inline_func>}}
 }
 
 # A list of all the static varibles defined in each scope.  The first
@@ -91,6 +161,29 @@ proc do_test {lang} {
 	set scopes_list $cxx_scopes_list
     }
 
+    # Print each scope/function using these syntaxes:
+    #
+    #  "(gdb) p 'S::method() const'"    # quoted
+    #  "(gdb) p S::method() const"      # unquoted
+    #
+    foreach scope_line $scopes_list  {
+	set scope [lindex $scope_line 0]
+
+	set print_quoted_re [lindex $scope_line 2]
+	set print_quoted_re [uplevel 1 "subst -nobackslashes -nocommands \"$print_quoted_re\""]
+
+	set print_unquoted_re [lindex $scope_line 3]
+	set print_unquoted_re [uplevel 1 "subst -nobackslashes -nocommands \"$print_unquoted_re\""]
+
+	gdb_test "print '${scope}'" $print_quoted_re
+
+	if {$print_unquoted_re != ""} {
+	    gdb_test "print ${scope}" $print_unquoted_re
+	} else {
+	    gdb_test "print ${scope}" $print_quoted_re
+	}
+    }
+
     # Print each variable using these syntaxes:
     #
     #  'func()'::var
diff --git a/gdb/valops.c b/gdb/valops.c
index 66678e5..f928eea 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3427,6 +3427,11 @@ value_struct_elt_for_reference (struct type *domain, int offset,
 	    {
 	      for (j = 0; j < len; ++j)
 		{
+		  if (TYPE_CONST (intype) != TYPE_FN_FIELD_CONST (f, j))
+		    continue;
+		  if (TYPE_VOLATILE (intype) != TYPE_FN_FIELD_VOLATILE (f, j))
+		    continue;
+
 		  if (compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 0)
 		      || compare_parameters (TYPE_FN_FIELD_TYPE (f, j),
 					     intype, 1))
