diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0cacee3cbb1..8f534a7032d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2009-08-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Support constant DW_AT_data_member_location by GCC PR debug/40659.
+	* dwarf2read.c
+	(dwarf2_add_field <DW_TAG_member> <DW_AT_data_member_location>):
+	Initialize BYTE_OFFSET to 0 by default.  Explicitly check if
+	attr_form_is_block.
+	(dwarf2_add_field <DW_TAG_inheritance> <DW_AT_data_member_location>)
+	(read_common_block <DW_AT_data_member_location>): New variable
+	byte_offset.  Fix crash on non-DW_BLOCK ATTR values.
+
 2009-08-28  Hui Zhu  <teawater@gmail.com>
 
 	* record.c (record_list_release_next): Change the first
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 445bab8c562..7f0442701e9 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4385,17 +4385,16 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
 	{
-          int byte_offset;
+          int byte_offset = 0;
 
           if (attr_form_is_section_offset (attr))
-            {
-              dwarf2_complex_location_expr_complaint ();
-              byte_offset = 0;
-            }
+	    dwarf2_complex_location_expr_complaint ();
           else if (attr_form_is_constant (attr))
             byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else
+          else if (attr_form_is_block (attr))
             byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+	  else
+	    dwarf2_complex_location_expr_complaint ();
 
           SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
 	}
@@ -4490,8 +4489,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       /* C++ base class field.  */
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
-	SET_FIELD_BITPOS (*fp, decode_locdesc (DW_BLOCK (attr), cu)
-			       * bits_per_byte);
+	{
+          int byte_offset = 0;
+
+          if (attr_form_is_section_offset (attr))
+	    dwarf2_complex_location_expr_complaint ();
+          else if (attr_form_is_constant (attr))
+            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+          else if (attr_form_is_block (attr))
+            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+	  else
+	    dwarf2_complex_location_expr_complaint ();
+
+          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
+	}
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = type_name_no_tag (fp->type);
@@ -5438,8 +5449,18 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 	  attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
 	  if (attr)
 	    {
-	      SYMBOL_VALUE_ADDRESS (sym) =
-		base + decode_locdesc (DW_BLOCK (attr), cu);
+	      CORE_ADDR byte_offset = 0;
+
+	      if (attr_form_is_section_offset (attr))
+		dwarf2_complex_location_expr_complaint ();
+	      else if (attr_form_is_constant (attr))
+		byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+	      else if (attr_form_is_block (attr))
+		byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+	      else
+		dwarf2_complex_location_expr_complaint ();
+
+	      SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
 	      add_symbol_to_list (sym, &global_symbols);
 	    }
 	  child_die = sibling_die (child_die);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 99c9c3db183..a07ed2a3cd6 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-08-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Support constant DW_AT_data_member_location by GCC PR debug/40659.
+	* gdb.dwarf2/dw2-inheritance.exp, gdb.dwarf2/dw2-inheritance.S: New.
+
 2009-08-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	* gdb.mi/mi2-var-cmd.exp (create variable with invalid FRAME-ADDR): New.
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S
new file mode 100644
index 00000000000..13c4e9826ed
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S
@@ -0,0 +1,98 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2009 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Test DW_TAG_inheritance using constant DW_AT_data_member_location
+   introduced by GCC PR debug/40659.  */
+
+/* Debug information */
+
+	.section .debug_info
+.Lcu1_begin:
+	/* CU header */
+	.4byte	.Lcu1_end - .Lcu1_start		/* Length of Compilation Unit */
+.Lcu1_start:
+	.2byte	2				/* DWARF Version */
+	.4byte	.Labbrev1_begin			/* Offset into abbrev section */
+	.byte	4				/* Pointer size */
+
+	/* CU die */
+	.uleb128 1				/* Abbrev: DW_TAG_compile_unit */
+	.4byte	.Lline1_begin			/* DW_AT_stmt_list */
+	.ascii	"file1.txt\0"			/* DW_AT_name */
+	.ascii	"GNU C 3.3.3\0"			/* DW_AT_producer */
+	.byte	4				/* DW_LANG_C_plus_plus (C++) */
+
+.Lbase:
+	.uleb128	3			/* Abbrev: DW_TAG_class_type */
+	.ascii		"base\0"		/* DW_AT_name */
+	.byte		4			/* DW_AT_byte_size */
+
+	.byte		0			/* End of children of "base" */
+
+	.uleb128	3			/* Abbrev: DW_TAG_class_type */
+	.ascii		"inherited\0"		/* DW_AT_name */
+	.byte		8			/* DW_AT_byte_size */
+
+	.uleb128	2			/* Abbrev: DW_TAG_inheritance */
+	.4byte		.Lbase-.Lcu1_begin	/* DW_AT_type */
+	.byte		0			/* DW_AT_data_member_location */
+
+	.byte		0			/* End of children of "inherited" */
+
+	.byte		0			/* End of children of CU */
+
+.Lcu1_end:
+
+/* Abbrev table */
+	.section .debug_abbrev
+.Labbrev1_begin:
+	.uleb128	1			/* Abbrev code */
+	.uleb128	0x11			/* DW_TAG_compile_unit */
+	.byte		1			/* has_children */
+	.uleb128	0x10			/* DW_AT_stmt_list */
+	.uleb128	0x6			/* DW_FORM_data4 */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x25			/* DW_AT_producer */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x13			/* DW_AT_language */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	2			/* Abbrev code */
+	.uleb128	0x1c			/* DW_TAG_inheritance */
+	.byte		0			/* has_children */
+	.uleb128	0x49			/* DW_AT_type */
+	.uleb128	0x13			/* DW_FORM_ref4 */
+	.uleb128	0x38			/* DW_AT_data_member_location */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	3			/* Abbrev code */
+	.uleb128	0x02			/* DW_TAG_class_type */
+	.byte		1			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0xb			/* DW_AT_byte_size */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inheritance.exp b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.exp
new file mode 100644
index 00000000000..2eb5b46cef6
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.exp
@@ -0,0 +1,40 @@
+# Copyright 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test DW_TAG_inheritance using constant DW_AT_data_member_location
+# introduced by GCC PR debug/40659.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    return 0  
+}
+
+set testfile "dw2-inheritance"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable}" object {nodebug}] != "" } {
+    return -1
+}
+
+clean_restart $executable
+
+gdb_test "ptype inherited" "type = class inherited .*"