PR breakpoints/14643.
authorDoug Evans <dje@google.com>
Thu, 11 Oct 2012 16:12:05 +0000 (16:12 +0000)
committerDoug Evans <dje@google.com>
Thu, 11 Oct 2012 16:12:05 +0000 (16:12 +0000)
* linespec.c (struct ls_parser): New member keyword_ok.
(linespec_lexer_lex_string): Add comment.
(linespec_lexer_lex_one): Ignore keywords if it's the wrong place
for one.
(parse_linespec): Set keyword_ok.

testsuite/
* gdb.linespec/ls-errs.exp: Change tests of "b if|task|thread".
* gdb.linespec/thread.c: New file.
* gdb.linespec/thread.exp: New file.

gdb/ChangeLog
gdb/linespec.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.linespec/ls-errs.exp
gdb/testsuite/gdb.linespec/thread.c [new file with mode: 0644]
gdb/testsuite/gdb.linespec/thread.exp [new file with mode: 0644]

index 7955f5ff11f96629387804c59bafda522bd82f23..8b07e47785084eedccb7b12f5bde1c967c0bb130 100644 (file)
@@ -1,3 +1,12 @@
+2012-10-11  Doug Evans  <dje@google.com>
+
+       PR breakpoints/14643.
+       * linespec.c (struct ls_parser): New member keyword_ok.
+       (linespec_lexer_lex_string): Add comment.
+       (linespec_lexer_lex_one): Ignore keywords if it's the wrong place
+       for one.
+       (parse_linespec): Set keyword_ok.
+
 2012-10-10  Doug Evans  <dje@google.com>
 
        * dwarf2read.c (process_psymtab_comp_unit_reader): Remove duplicate
index 3edc09f12c02ba1b58f86810daef89474b7713fe..06634d28394c333ef2b6dadfd7f2f4dc19e80adf 100644 (file)
@@ -286,6 +286,11 @@ struct ls_parser
   /* Is the entire linespec quote-enclosed?  */
   int is_quote_enclosed;
 
+  /* Is a keyword syntactically valid at this point?
+     In, e.g., "break thread thread 1", the leading "keyword" must not
+     be interpreted as such.  */
+  int keyword_ok;
+
   /* The state of the parse.  */
   struct linespec_state state;
 #define PARSER_STATE(PPTR) (&(PPTR)->state)
@@ -607,6 +612,10 @@ linespec_lexer_lex_string (linespec_parser *parser)
          if (isspace (*PARSER_STREAM (parser)))
            {
              p = skip_spaces (PARSER_STREAM (parser));
+             /* When we get here we know we've found something followed by
+                a space (we skip over parens and templates below).
+                So if we find a keyword now, we know it is a keyword and not,
+                say, a function name.  */
              if (linespec_lexer_lex_keyword (p) != NULL)
                {
                  LS_TOKEN_STOKEN (token).ptr = start;
@@ -716,8 +725,10 @@ linespec_lexer_lex_one (linespec_parser *parser)
       /* Skip any whitespace.  */
       PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser));
 
-      /* Check for a keyword.  */
-      keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
+      /* Check for a keyword, they end the linespec.  */
+      keyword = NULL;
+      if (parser->keyword_ok)
+       keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
       if (keyword != NULL)
        {
          parser->lexer.current.type = LSTOKEN_KEYWORD;
@@ -2024,6 +2035,10 @@ parse_linespec (linespec_parser *parser, char **argptr)
        }
     }
 
+  /* A keyword at the start cannot be interpreted as such.
+     Consider "b thread thread 42".  */
+  parser->keyword_ok = 0;
+
   parser->lexer.saved_arg = *argptr;
   parser->lexer.stream = argptr;
   file_exception.reason = 0;
@@ -2098,6 +2113,9 @@ parse_linespec (linespec_parser *parser, char **argptr)
   else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER)
     unexpected_linespec_error (parser);
 
+  /* Now we can recognize keywords.  */
+  parser->keyword_ok = 1;
+
   /* Shortcut: If the next token is not LSTOKEN_COLON, we know that
      this token cannot represent a filename.  */
   token = linespec_lexer_peek_token (parser);
index b58e35172558a9ee7237096898a59aa171c85067..4354197234e6f1751f656d20e2747436cba53deb 100644 (file)
@@ -1,5 +1,10 @@
 2012-10-11  Doug Evans  <dje@google.com>
 
+       PR breakpoints/14643.
+       * gdb.linespec/ls-errs.exp: Change tests of "b if|task|thread".
+       * gdb.linespec/thread.c: New file.
+       * gdb.linespec/thread.exp: New file.
+
        * lib/gdb.exp (gdb_breakpoint): Fix varargs scan.
        Recognize "message" -> print pass and fail.  Add eof case.
        (runto): Recognize message, no-message.  Print pass/fail if requested,
index 5668397a3b054d12a9a31385513e2fb27e26a46b..7ee2623a9fbbb82c06f3e66a4944cbf378173284 100644 (file)
@@ -171,7 +171,7 @@ foreach x {"3" "+100" "-100" "foo"} {
 }
 
 foreach x {"if" "task" "thread"} {
-    add the_tests $x unexpected_opt "keyword" $x
+    add the_tests $x invalid_function $x
 }
 
 add the_tests "'main.c'flubber" unexpected_opt "string" "flubber"
diff --git a/gdb/testsuite/gdb.linespec/thread.c b/gdb/testsuite/gdb.linespec/thread.c
new file mode 100644 (file)
index 0000000..185e4a3
--- /dev/null
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 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/>.  */
+
+/* http://sourceware.org/bugzilla/show_bug.cgi?id=14643 */
+
+static void
+thread ()
+{
+}
+
+int
+main ()
+{
+  int x = 0;
+  thread (); /* set breakpoint 1 here */
+  return x;
+}
diff --git a/gdb/testsuite/gdb.linespec/thread.exp b/gdb/testsuite/gdb.linespec/thread.exp
new file mode 100644 (file)
index 0000000..1e8ee46
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright 2012 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/>.
+
+# http://sourceware.org/bugzilla/show_bug.cgi?id=14643
+# gdb 7.5 thinks "thread" is a linespec keyword.
+
+standard_testfile
+set exefile $testfile
+
+if {[prepare_for_testing $testfile $exefile $srcfile {debug}]} {
+    return -1
+}
+
+if ![runto_main] {
+    fail "Can't run to main"
+    return 0
+}
+
+set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
+
+gdb_test "break $srcfile:$bp_location1" \
+    "Breakpoint.*at.* file .*$srcfile, line $bp_location1\\." \
+    "breakpoint line number in file"
+
+gdb_continue_to_breakpoint "$bp_location1"
+
+gdb_breakpoint "thread" "message"
+
+gdb_continue_to_breakpoint "thread function"