This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: PR macros/7961


I'm checking this in.

This fixes PR macros/7961, a macro scoping bug.  I submitted a somewhat
different fix for this long ago:

    http://sourceware.org/ml/gdb-patches/2008-09/msg00046.html

I'm finally resurrecting it.  This time, instead of replacing the
expression context block with a SAL, I added a PC argument.  Then I
updated the callers; most of the patch is straightforward

Built and regtested on x86-64 Fedora 16.
I've included a new test case.

Tom

2012-06-27  Tom Tromey  <tromey@redhat.com>

	PR macros/7961:
	* varobj.c (varobj_create): Update.
	(varobj_set_value): Update.
	* tracepoint.c (validate_actionline): Update.
	(encode_actions_1): Update.
	* parse.c (parse_exp_1): Add 'pc' argument.
	(parse_exp_in_context): Add 'pc' argument.  Change how
	expression_context_pc is set.
	(parse_expression): Update.
	(parse_field_expression): Update.
	* expression.h (parse_exp_1): Update.
	* eval.c (parse_to_comma_and_eval): Update.
	* breakpoint.c (set_breakpoint_condition): Update.
	(update_watchpoint): Update.
	(init_breakpoint_sal): Update
	(find_condition_and_thread): Update.
	(watch_command_1): Update.
	(update_breakpoint_locations): Update.
	* ada-lang.c (ada_read_renaming_var_value): Update.
	(create_excep_cond_exprs): Update.

2012-06-27  Tom Tromey  <tromey@redhat.com>

	* gdb.base/macscp1.c (macscp_expr): Add breakpoint comment.
	* gdb.base/macscp.exp (maybe_kfail): Add test for macro scope.

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 7afcef8..aa090af 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -4060,7 +4060,7 @@ ada_read_renaming_var_value (struct symbol *renaming_sym,
 
   sym_name = xstrdup (SYMBOL_LINKAGE_NAME (renaming_sym));
   old_chain = make_cleanup (xfree, sym_name);
-  expr = parse_exp_1 (&sym_name, block, 0);
+  expr = parse_exp_1 (&sym_name, 0, block, 0);
   make_cleanup (free_current_contents, &expr);
   value = evaluate_expression (expr);
 
@@ -11140,7 +11140,8 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
 	  s = cond_string;
 	  TRY_CATCH (e, RETURN_MASK_ERROR)
 	    {
-	      exp = parse_exp_1 (&s, block_for_pc (bl->address), 0);
+	      exp = parse_exp_1 (&s, bl->address,
+				 block_for_pc (bl->address), 0);
 	    }
 	  if (e.reason < 0)
 	    warning (_("failed to reevaluate internal exception condition "
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 12ab271..71a5e19 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -926,7 +926,7 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
 
 	  innermost_block = NULL;
 	  arg = exp;
-	  w->cond_exp = parse_exp_1 (&arg, 0, 0);
+	  w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
 	  if (*arg)
 	    error (_("Junk at end of expression"));
 	  w->cond_exp_valid_block = innermost_block;
@@ -939,7 +939,8 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
 	    {
 	      arg = exp;
 	      loc->cond =
-		parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+		parse_exp_1 (&arg, loc->address,
+			     block_for_pc (loc->address), 0);
 	      if (*arg)
 		error (_("Junk at end of expression"));
 	    }
@@ -1731,7 +1732,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
 	  b->exp = NULL;
 	}
       s = b->exp_string_reparse ? b->exp_string_reparse : b->exp_string;
-      b->exp = parse_exp_1 (&s, b->exp_valid_block, 0);
+      b->exp = parse_exp_1 (&s, 0, b->exp_valid_block, 0);
       /* If the meaning of expression itself changed, the old value is
 	 no longer relevant.  We don't want to report a watchpoint hit
 	 to the user when the old value and the new value may actually
@@ -1752,7 +1753,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
 	    }
 
 	  s = b->base.cond_string;
-	  b->cond_exp = parse_exp_1 (&s, b->cond_exp_valid_block, 0);
+	  b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
 	}
     }
 
@@ -8765,7 +8766,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
       if (b->cond_string)
 	{
 	  char *arg = b->cond_string;
-	  loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+	  loc->cond = parse_exp_1 (&arg, loc->address,
+				   block_for_pc (loc->address), 0);
 	  if (*arg)
               error (_("Garbage '%s' follows condition"), arg);
 	}
@@ -9052,7 +9054,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
 	  struct expression *expr;
 
 	  tok = cond_start = end_tok + 1;
-	  expr = parse_exp_1 (&tok, block_for_pc (pc), 0);
+	  expr = parse_exp_1 (&tok, pc, block_for_pc (pc), 0);
 	  xfree (expr);
 	  cond_end = tok;
 	  *cond_string = savestring (cond_start, cond_end - cond_start);
@@ -10572,7 +10574,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   /* Parse the rest of the arguments.  */
   innermost_block = NULL;
   exp_start = arg;
-  exp = parse_exp_1 (&arg, 0, 0);
+  exp = parse_exp_1 (&arg, 0, 0, 0);
   exp_end = arg;
   /* Remove trailing whitespace from the expression before saving it.
      This makes the eventual display of the expression string a bit
@@ -10627,7 +10629,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
 
       innermost_block = NULL;
       tok = cond_start = end_tok + 1;
-      cond = parse_exp_1 (&tok, 0, 0);
+      cond = parse_exp_1 (&tok, 0, 0, 0);
 
       /* The watchpoint expression may not be local, but the condition
 	 may still be.  E.g.: `watch global if local > 0'.  */
@@ -13677,7 +13679,8 @@ update_breakpoint_locations (struct breakpoint *b,
 	  s = b->cond_string;
 	  TRY_CATCH (e, RETURN_MASK_ERROR)
 	    {
-	      new_loc->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 
+	      new_loc->cond = parse_exp_1 (&s, sals.sals[i].pc,
+					   block_for_pc (sals.sals[i].pc), 
 					   0);
 	    }
 	  if (e.reason < 0)
diff --git a/gdb/eval.c b/gdb/eval.c
index 7f1dfac..3d43406 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -125,7 +125,7 @@ parse_and_eval (char *exp)
 struct value *
 parse_to_comma_and_eval (char **expp)
 {
-  struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);
+  struct expression *expr = parse_exp_1 (expp, 0, (struct block *) 0, 1);
   struct value *val;
   struct cleanup *old_chain =
     make_cleanup (free_current_contents, &expr);
diff --git a/gdb/expression.h b/gdb/expression.h
index ace58f2..004a60e 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -100,7 +100,8 @@ extern struct expression *parse_expression (char *);
 
 extern struct type *parse_field_expression (char *, char **);
 
-extern struct expression *parse_exp_1 (char **, struct block *, int);
+extern struct expression *parse_exp_1 (char **, CORE_ADDR pc, struct block *,
+				       int);
 
 /* For use by parsers; set if we want to parse an expression and
    attempt to complete a field name.  */
diff --git a/gdb/parse.c b/gdb/parse.c
index 0d0467d..c372f40 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -116,7 +116,8 @@ static void free_funcalls (void *ignore);
 static int prefixify_subexp (struct expression *, struct expression *, int,
 			     int);
 
-static struct expression *parse_exp_in_context (char **, struct block *, int, 
+static struct expression *parse_exp_in_context (char **, CORE_ADDR,
+						struct block *, int, 
 						int, int *);
 
 void _initialize_parse (void);
@@ -1097,9 +1098,9 @@ prefixify_subexp (struct expression *inexpr,
    If COMMA is nonzero, stop if a comma is reached.  */
 
 struct expression *
-parse_exp_1 (char **stringptr, struct block *block, int comma)
+parse_exp_1 (char **stringptr, CORE_ADDR pc, struct block *block, int comma)
 {
-  return parse_exp_in_context (stringptr, block, comma, 0, NULL);
+  return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL);
 }
 
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
@@ -1110,8 +1111,8 @@ parse_exp_1 (char **stringptr, struct block *block, int comma)
    is left untouched.  */
 
 static struct expression *
-parse_exp_in_context (char **stringptr, struct block *block, int comma, 
-		      int void_context_p, int *out_subexp)
+parse_exp_in_context (char **stringptr, CORE_ADDR pc, struct block *block,
+		      int comma, int void_context_p, int *out_subexp)
 {
   volatile struct gdb_exception except;
   struct cleanup *old_chain;
@@ -1138,8 +1139,10 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma,
   /* If no context specified, try using the current frame, if any.  */
   if (!expression_context_block)
     expression_context_block = get_selected_block (&expression_context_pc);
-  else
+  else if (pc == 0)
     expression_context_pc = BLOCK_START (expression_context_block);
+  else
+    expression_context_pc = pc;
 
   /* Fall back to using the current source static context, if any.  */
 
@@ -1227,7 +1230,7 @@ parse_expression (char *string)
 {
   struct expression *exp;
 
-  exp = parse_exp_1 (&string, 0, 0);
+  exp = parse_exp_1 (&string, 0, 0, 0);
   if (*string)
     error (_("Junk after end of expression."));
   return exp;
@@ -1252,7 +1255,7 @@ parse_field_expression (char *string, char **name)
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
       in_parse_field = 1;
-      exp = parse_exp_in_context (&string, 0, 0, 0, &subexp);
+      exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
     }
   in_parse_field = 0;
   if (except.reason < 0 || ! exp)
diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index 5f29204..1f995d5 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -440,6 +440,17 @@ gdb_test "break [gdb_get_line_number "set breakpoint here"]" \
     "Breakpoint.*at.* file .*, line.*" \
     "breakpoint macscp_expr"
 
+gdb_test "cond \$bpnum foo == MACRO_TO_EXPAND" \
+  "No symbol \"MACRO_TO_EXPAND\" in current context\." \
+  "macro MACRO_TO_EXPAND not in scope at breakpoint"
+
+# Note that we choose the condition so that this breakpoint never
+# stops.
+set l2 [gdb_get_line_number "set second breakpoint here"]
+gdb_test "break $l2  if foo != MACRO_TO_EXPAND" \
+  "Breakpoint.*at.*" \
+  "breakpoint macscp_expr using MACRO_TO_EXPAND"
+
 gdb_test "continue" "foo = 0;.*" "continue to macsp_expr"
 
 gdb_test "print address.addr" \
@@ -450,7 +461,7 @@ gdb_test "print MACRO_TO_EXPAND" \
     "No symbol \"MACRO_TO_EXPAND\" in current context\." \
     "print expression with macro before define."
 
-gdb_test "next" "foo = 1;" "next to definition 1"
+gdb_test "next" "foo = 1;.*here.*/" "next to definition 1"
 
 gdb_test "print MACRO_TO_EXPAND" \
     " = 0" \
diff --git a/gdb/testsuite/gdb.base/macscp1.c b/gdb/testsuite/gdb.base/macscp1.c
index b1eb0b4..09a4c0d 100644
--- a/gdb/testsuite/gdb.base/macscp1.c
+++ b/gdb/testsuite/gdb.base/macscp1.c
@@ -89,7 +89,7 @@ macscp_expr (void)
 
   foo = 0;  /* set breakpoint here */
 #define MACRO_TO_EXPAND foo
-  foo = 1;
+  foo = 1;			/* set second breakpoint here */
 #undef MACRO_TO_EXPAND
   foo = 2;			/* stopping point for line test */
 }
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 6d76f4b..e4fd2d3 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -734,7 +734,8 @@ validate_actionline (char **line, struct breakpoint *b)
 	  for (loc = t->base.loc; loc; loc = loc->next)
 	    {
 	      p = tmp_p;
-	      exp = parse_exp_1 (&p, block_for_pc (loc->address), 1);
+	      exp = parse_exp_1 (&p, loc->address,
+				 block_for_pc (loc->address), 1);
 	      old_chain = make_cleanup (free_current_contents, &exp);
 
 	      if (exp->elts[0].opcode == OP_VAR_VALUE)
@@ -787,7 +788,8 @@ validate_actionline (char **line, struct breakpoint *b)
 	    {
 	      p = tmp_p;
 	      /* Only expressions are allowed for this action.  */
-	      exp = parse_exp_1 (&p, block_for_pc (loc->address), 1);
+	      exp = parse_exp_1 (&p, loc->address,
+				 block_for_pc (loc->address), 1);
 	      old_chain = make_cleanup (free_current_contents, &exp);
 
 	      /* We have something to evaluate, make sure that the expr to
@@ -1452,7 +1454,7 @@ encode_actions_1 (struct command_line *action,
 		  struct cleanup *old_chain = NULL;
 		  struct cleanup *old_chain1 = NULL;
 
-		  exp = parse_exp_1 (&action_exp, 
+		  exp = parse_exp_1 (&action_exp, tloc->address,
 				     block_for_pc (tloc->address), 1);
 		  old_chain = make_cleanup (free_current_contents, &exp);
 
@@ -1542,7 +1544,7 @@ encode_actions_1 (struct command_line *action,
 		  struct cleanup *old_chain = NULL;
 		  struct cleanup *old_chain1 = NULL;
 
-		  exp = parse_exp_1 (&action_exp, 
+		  exp = parse_exp_1 (&action_exp, tloc->address,
 				     block_for_pc (tloc->address), 1);
 		  old_chain = make_cleanup (free_current_contents, &exp);
 
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 3086499..42e2ce4 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -624,6 +624,7 @@ varobj_create (char *objname,
       enum varobj_languages lang;
       struct value *value = NULL;
       volatile struct gdb_exception except;
+      CORE_ADDR pc;
 
       /* Parse and evaluate the expression, filling in as much of the
          variable's data as possible.  */
@@ -650,9 +651,13 @@ varobj_create (char *objname,
       if (type == USE_SELECTED_FRAME)
 	var->root->floating = 1;
 
+      pc = 0;
       block = NULL;
       if (fi != NULL)
-	block = get_frame_block (fi, 0);
+	{
+	  block = get_frame_block (fi, 0);
+	  pc = get_frame_pc (fi);
+	}
 
       p = expression;
       innermost_block = NULL;
@@ -660,7 +665,7 @@ varobj_create (char *objname,
          return a sensible error.  */
       TRY_CATCH (except, RETURN_MASK_ERROR)
 	{
-	  var->root->exp = parse_exp_1 (&p, block, 0);
+	  var->root->exp = parse_exp_1 (&p, pc, block, 0);
 	}
 
       if (except.reason < 0)
@@ -1471,7 +1476,7 @@ varobj_set_value (struct varobj *var, char *expression)
   gdb_assert (varobj_editable_p (var));
 
   input_radix = 10;		/* ALWAYS reset to decimal temporarily.  */
-  exp = parse_exp_1 (&s, 0, 0);
+  exp = parse_exp_1 (&s, 0, 0, 0);
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
       value = evaluate_expression (exp);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]