[gdb] Fix explicit Class:: inside class scope (BZ 874817, Keith Seitz).

Jan Kratochvil jankratochvil at fedoraproject.org
Sat Nov 9 18:28:16 UTC 2013


commit 2d6d1b2f5827322fad8e6b06e4c107a9653bb7b1
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Sat Nov 9 19:27:47 2013 +0100

    Fix explicit Class:: inside class scope (BZ 874817, Keith Seitz).

 gdb-implicit-this.patch |  299 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb.spec                |    9 ++-
 2 files changed, 307 insertions(+), 1 deletions(-)
---
diff --git a/gdb-implicit-this.patch b/gdb-implicit-this.patch
new file mode 100644
index 0000000..0ce72dd
--- /dev/null
+++ b/gdb-implicit-this.patch
@@ -0,0 +1,299 @@
+Index: gdb-7.6.50.20130731-cvs/gdb/c-exp.y
+===================================================================
+--- gdb-7.6.50.20130731-cvs.orig/gdb/c-exp.y	2013-11-09 18:41:48.706718127 +0100
++++ gdb-7.6.50.20130731-cvs/gdb/c-exp.y	2013-11-09 18:42:19.291697661 +0100
+@@ -2944,6 +2944,30 @@ classify_inner_name (const struct block
+     {
+     case LOC_BLOCK:
+     case LOC_LABEL:
++      {
++	struct field_of_this_result fot;
++
++	/* We might have erroneously found a constructor where we wanted
++	   a type name.  The trick is ascertaining what the user wanted.
++	   If cp_lookup_nested_symbol found a constructor, but it is for a
++	   different type than CONTEXT, then this is really a type, not a
++	   constructor.  Look for the type and return that.  */
++	memset (&fot, 0, sizeof (fot));
++	check_field (type, copy, &fot);
++	if (fot.fn_field != NULL
++	    && TYPE_FN_FIELD_CONSTRUCTOR (fot.fn_field->fn_fields, 0)
++	    && !types_equal (type, fot.type))
++	  {
++	    struct symbol *sym;
++
++	    sym = lookup_symbol (copy, block, STRUCT_DOMAIN, NULL);
++	    if (sym != NULL)
++	      {
++		yylval.tsym.type = SYMBOL_TYPE (sym);
++		return TYPENAME;
++	      }
++	  }
++      }
+       return ERROR;
+ 
+     case LOC_TYPEDEF:
+Index: gdb-7.6.50.20130731-cvs/gdb/symtab.c
+===================================================================
+--- gdb-7.6.50.20130731-cvs.orig/gdb/symtab.c	2013-11-09 18:41:48.708718125 +0100
++++ gdb-7.6.50.20130731-cvs/gdb/symtab.c	2013-11-09 18:42:19.293697660 +0100
+@@ -1293,7 +1293,7 @@ lookup_language_this (const struct langu
+    return 1 if the component named NAME from the ultimate target
+    structure/union is defined, otherwise, return 0.  */
+ 
+-static int
++int
+ check_field (struct type *type, const char *name,
+ 	     struct field_of_this_result *is_a_field_of_this)
+ {
+Index: gdb-7.6.50.20130731-cvs/gdb/symtab.h
+===================================================================
+--- gdb-7.6.50.20130731-cvs.orig/gdb/symtab.h	2013-11-09 18:42:19.293697660 +0100
++++ gdb-7.6.50.20130731-cvs/gdb/symtab.h	2013-11-09 18:42:34.023687872 +0100
+@@ -1377,4 +1377,9 @@ void initialize_symbol (struct symbol *)
+ 
+ struct template_symbol *allocate_template_symbol (struct objfile *);
+ 
++/* See comment in symtab.c.  */
++
++int check_field (struct type *type, const char *name,
++		 struct field_of_this_result *is_a_field_of_this);
++
+ #endif /* !defined(SYMTAB_H) */
+Index: gdb-7.6.50.20130731-cvs/gdb/valops.c
+===================================================================
+--- gdb-7.6.50.20130731-cvs.orig/gdb/valops.c	2013-11-09 18:41:48.712718123 +0100
++++ gdb-7.6.50.20130731-cvs/gdb/valops.c	2013-11-09 18:42:19.294697659 +0100
+@@ -3226,10 +3226,35 @@ value_struct_elt_for_reference (struct t
+ 	    return value_from_longest
+ 	      (lookup_memberptr_type (TYPE_FIELD_TYPE (t, i), domain),
+ 	       offset + (TYPE_FIELD_BITPOS (t, i) >> 3));
+-	  else if (noside == EVAL_AVOID_SIDE_EFFECTS)
++	  else if (noside != EVAL_NORMAL)
+ 	    return allocate_value (TYPE_FIELD_TYPE (t, i));
+ 	  else
+-	    error (_("Cannot reference non-static field \"%s\""), name);
++	    {
++	      /* Try to evaluate NAME as a qualified name with implicit
++		 this pointer.  In this case, attempt to return the
++		 equivalent to `this->*(&TYPE::NAME)'.  */
++	      v = value_of_this_silent (current_language);
++	      if (v != NULL)
++		{
++		  struct value *ptr;
++		  long mem_offset;
++		  struct type *type, *tmp;
++
++		  ptr = value_aggregate_elt (domain, name, NULL, 1, noside);
++		  type = check_typedef (value_type (ptr));
++		  gdb_assert (type != NULL
++			      && TYPE_CODE (type) == TYPE_CODE_MEMBERPTR);
++		  tmp = lookup_pointer_type (TYPE_DOMAIN_TYPE (type));
++		  v = value_cast_pointers (tmp, v, 1);
++		  mem_offset = value_as_long (ptr);
++		  tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type));
++		  result = value_from_pointer (tmp,
++					       value_as_long (v) + mem_offset);
++		  return value_ind (result);
++		}
++
++	      error (_("Cannot reference non-static field \"%s\""), name);
++	    }
+ 	}
+     }
+ 
+Index: gdb-7.6.50.20130731-cvs/gdb/testsuite/gdb.cp/impl-this.cc
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.6.50.20130731-cvs/gdb/testsuite/gdb.cp/impl-this.cc	2013-11-09 18:42:19.294697659 +0100
+@@ -0,0 +1,96 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2013 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/>.  */
++
++#ifdef DEBUG
++#include <stdio.h>
++#endif
++
++class A
++{
++public:
++  int i;
++  int z;
++  A () : i (1), z (10) {}
++};
++
++class B : public virtual A
++{
++public:
++  int i;
++  B () : i (2) {}
++};
++
++class C : public virtual A
++{
++public:
++  int i;
++  int c;
++  C () : i (3), c (30) {}
++};
++
++class D : public B, public C
++{
++public:
++  int i;
++  int x;
++  D () : i (4), x (40) {}
++
++#ifdef DEBUG
++#define SUM(X)					\
++  do						\
++    {						\
++      sum += (X);				\
++      printf ("" #X " = %d\n", (X));		\
++    }						\
++  while (0)
++#else
++#define SUM(X) sum += (X)
++#endif
++
++int
++f (void)
++  {
++    int sum = 0;
++
++    SUM (i);
++    SUM (D::i);
++    SUM (D::B::i);
++    SUM (B::i);
++    SUM (D::C::i);
++    SUM (C::i);
++    SUM (D::B::A::i);
++    SUM (B::A::i);
++    SUM (A::i);
++    SUM (D::C::A::i);
++    SUM (C::A::i);
++    SUM (D::x);
++    SUM (x);
++    SUM (D::C::c);
++    SUM (C::c);
++    SUM (c);
++
++    return sum;
++  }
++};
++
++int
++main (void)
++{
++  D d;
++
++  return d.f ();
++}
+Index: gdb-7.6.50.20130731-cvs/gdb/testsuite/gdb.cp/impl-this.exp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.6.50.20130731-cvs/gdb/testsuite/gdb.cp/impl-this.exp	2013-11-09 18:42:19.295697659 +0100
+@@ -0,0 +1,89 @@
++# Copyright 2013 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/>.
++
++# This file is part of the gdb testsuite
++
++# Test expressions which assume an implicit "this" with a qualified
++# name.
++
++if {[skip_cplus_tests]} { continue }
++
++standard_testfile .cc
++
++if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
++    return -1
++}
++
++# First test expressions when there is no context.
++gdb_test "print i" "No symbol \"i\" in current context."
++gdb_test "print D::i" "Cannot reference non-static field \"i\""
++gdb_test "print D::B::i" "Cannot reference non-static field \"i\""
++gdb_test "print B::i" "Cannot reference non-static field \"i\""
++gdb_test "print D::C::i" "Cannot reference non-static field \"i\""
++gdb_test "print C::i" "Cannot reference non-static field \"i\""
++gdb_test "print D::B::A::i" "Cannot reference non-static field \"i\""
++gdb_test "print B::A::i" "Cannot reference non-static field \"i\""
++gdb_test "print A::i" "Cannot reference non-static field \"i\""
++gdb_test "print D::C::A::i" "Cannot reference non-static field \"i\""
++gdb_test "print C::A::i" "Cannot reference non-static field \"i\""
++gdb_test "print D::x" "Cannot reference non-static field \"x\""
++gdb_test "print x" "No symbol \"x\" in current context."
++gdb_test "print D::C::c" "Cannot reference non-static field \"c\""
++gdb_test "print C::c" "Cannot reference non-static field \"c\""
++gdb_test "print c" "No symbol \"c\" in current context."
++
++# Run to D::f.
++if {![runto_main]} {
++    perror "couldn't run to main"
++    continue
++}
++
++gdb_breakpoint "D::f"
++gdb_continue_to_breakpoint "run to D::f"
++
++# Now test valid expressions in the class hierarchy for D.
++gdb_test "print i" "= 4"
++gdb_test "print D::i" "= 4"
++gdb_test "print D::B::i" "= 2"
++gdb_test "print B::i" "= 2"
++gdb_test "print D::C::i" "= 3"
++gdb_test "print C::i" "= 3"
++gdb_test "print D::B::A::i" "= 1"
++gdb_test "print B::A::i" "= 1"
++gdb_test "print A::i" "= 1"
++gdb_test "print D::C::A::i" "= 1"
++gdb_test "print C::A::i" "= 1"
++gdb_test "print D::x" "= 40"
++gdb_test "print x" "= 40"
++gdb_test "print D::C::c" "= 30"
++gdb_test "print C::c" "= 30"
++gdb_test "print c" "= 30"
++
++# Test some invalid expressions
++gdb_test "print D::B::c" "There is no field named c"
++gdb_test "print D::B::A::c" "There is no field named c"
++gdb_test "print D::C::A::c" "There is no field named c"
++gdb_test "print B::c" "There is no field named c"
++gdb_test "print B::A::c" "There is no field named c"
++gdb_test "print C::A::c" "There is no field named c"
++gdb_test "print D::B::x" "There is no field named x"
++gdb_test "print D::B::A::x" "There is no field named x"
++gdb_test "print B::x" "There is no field named x"
++gdb_test "print B::A::x" "There is no field named x"
++gdb_test "print D::C::x" "There is no field named x"
++gdb_test "print C::x" "There is no field named x"
++gdb_test "print D::C::A::x" "There is no field named x"
++gdb_test "print C::A::x" "There is no field named x"
++
diff --git a/gdb.spec b/gdb.spec
index adbeb7c..be5a304 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -38,7 +38,7 @@ Version: 7.6.50.%{snap}
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 15%{?dist}
+Release: 16%{?dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
 Group: Development/Debuggers
@@ -529,6 +529,9 @@ Patch843: gdb-enable-count-crash.patch
 # RH BZ 1013453).
 Patch844: gdb-rhbz1013453-value-struct-elt-memory-leak.patch
 
+# Fix explicit Class:: inside class scope (BZ 874817, Keith Seitz).
+Patch845: gdb-implicit-this.patch
+
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
 # RL_STATE_FEDORA_GDB would not be found for:
 # Patch642: gdb-readline62-ask-more-rh.patch
@@ -822,6 +825,7 @@ find -name "*.info*"|xargs rm -f
 %patch832 -p1
 %patch843 -p1
 %patch844 -p1
+%patch845 -p1
 
 %patch393 -p1
 %if 0%{!?el5:1} || 0%{?scl:1}
@@ -1340,6 +1344,9 @@ fi
 %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
 
 %changelog
+* Sat Nov  9 2013 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.6.50.20130731-16.fc20
+- Fix explicit Class:: inside class scope (BZ 874817, Keith Seitz).
+
 * Tue Nov  5 2013 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.6.50.20130731-15.fc20
 - [aarch64] Backport two fixes (BZ 1026484).
 


More information about the scm-commits mailing list