This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] PR c++/14177 - Fix parsing TYPENAME:: in parentheses
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 31 May 2012 00:30:43 +0200
- Subject: [patch] PR c++/14177 - Fix parsing TYPENAME:: in parentheses
Hi,
p CV_f(CV::i)
-A syntax error in expression, near `i)'.
-(gdb) FAIL: gdb.cp/cpexprs.exp: p CV_f(CV::i)
+$136 = 43
+(gdb) PASS: gdb.cp/cpexprs.exp: p CV_f(CV::i)
when 'int i' is in class CV. I have just hit this during debugging.
I am very unsure with the C++ parser code but it seems OK to me.
That newly filed PR c++/14186 defect existed even before, I have just
testcased and filed it.
No regressions on {x86_64,x86_64-m32,i686}-fedora17-linux-gnu.
Thanks,
Jan
gdb/
2012-05-31 Jan Kratochvil <jan.kratochvil@redhat.com>
PR c++/14177 - Fix parsing TYPENAME:: in parentheses.
* c-exp.y (arglist_final): New rule, use nonempty_typelist from former
exp rule.
(exp(arglist)): Change arglist to arglist_final. Suppress OP_FUNCALL
if TYPE_INSTANCE is already pushed. Add const_or_volatile.
(exp(nonempty_typelist)const_or_volatile): Remove; move above.
gdb/testsuite/
2012-05-30 Jan Kratochvil <jan.kratochvil@redhat.com>
PR c++/14177 - Fix parsing TYPENAME:: in parentheses.
* gdb.cp/cpexprs.cc (class CV, CV::i, ATTRIBUTE_USED, CV_f): New.
(test_function): Call CV_f.
* gdb.cp/cpexprs.exp (p 'CV::m(int)', p CV::m(int))
(p 'CV::m(int) const', p CV::m(int) const, p 'CV::m(int) volatile')
(p CV::m(int) volatile, p 'CV::m(int) const volatile')
(p CV::m(int) const volatile, p CV_f(int), p CV_f(CV::t))
(p CV_f(CV::i)): New tests.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index e912657..39d5267 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -388,14 +388,36 @@ exp : exp '[' exp1 ']'
{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
;
+arglist_final
+ : arglist
+ | nonempty_typelist
+ { int i;
+ write_exp_elt_opcode (TYPE_INSTANCE);
+ write_exp_elt_longcst ((LONGEST) $<ivec>1[0]);
+ for (i = 0; i < $<ivec>1[0]; ++i)
+ write_exp_elt_type ($<tvec>1[i + 1]);
+ write_exp_elt_longcst((LONGEST) $<ivec>1[0]);
+ write_exp_elt_opcode (TYPE_INSTANCE);
+ free ($1);
+ }
+ ;
+
exp : exp '('
/* This is to save the value of arglist_len
being accumulated by an outer function call. */
{ start_arglist (); }
- arglist ')' %prec ARROW
- { write_exp_elt_opcode (OP_FUNCALL);
- write_exp_elt_longcst ((LONGEST) end_arglist ());
- write_exp_elt_opcode (OP_FUNCALL); }
+ arglist_final ')' const_or_volatile %prec ARROW
+ { if (expout_ptr
+ && (expout->elts[expout_ptr - 1].opcode
+ != TYPE_INSTANCE))
+ {
+ write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_FUNCALL);
+ }
+ else
+ end_arglist ();
+ }
;
exp : UNKNOWN_CPP_NAME '('
@@ -436,18 +458,6 @@ arglist : arglist ',' exp %prec ABOVE_COMMA
{ arglist_len++; }
;
-exp : exp '(' nonempty_typelist ')' const_or_volatile
- { int i;
- write_exp_elt_opcode (TYPE_INSTANCE);
- write_exp_elt_longcst ((LONGEST) $<ivec>3[0]);
- for (i = 0; i < $<ivec>3[0]; ++i)
- write_exp_elt_type ($<tvec>3[i + 1]);
- write_exp_elt_longcst((LONGEST) $<ivec>3[0]);
- write_exp_elt_opcode (TYPE_INSTANCE);
- free ($3);
- }
- ;
-
rcurly : '}'
{ $$ = end_arglist () - 1; }
;
diff --git a/gdb/testsuite/gdb.cp/cpexprs.cc b/gdb/testsuite/gdb.cp/cpexprs.cc
index c8c5ac8..f6b355c 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.cc
+++ b/gdb/testsuite/gdb.cp/cpexprs.cc
@@ -308,6 +308,29 @@ class derived : public base1, public base2
int foo_;
};
+class CV { public:
+ static const int i;
+ typedef int t;
+ void m(t);
+ void m(t) const;
+ void m(t) volatile;
+ void m(t) const volatile;
+};
+const int CV::i = 42;
+#ifdef __GNUC__
+# define ATTRIBUTE_USED __attribute__((used))
+#else
+# define ATTRIBUTE_USED
+#endif
+ATTRIBUTE_USED void CV::m(CV::t) {}
+ATTRIBUTE_USED void CV::m(CV::t) const {}
+ATTRIBUTE_USED void CV::m(CV::t) volatile {}
+ATTRIBUTE_USED void CV::m(CV::t) const volatile {}
+int CV_f (int x)
+{
+ return x + 1;
+}
+
int
test_function (int argc, char* argv[]) // test_function
{ // test_function
@@ -428,6 +451,8 @@ test_function (int argc, char* argv[]) // test_function
fluff* flp = a;
fluff** flpp = a;
+ CV_f(CV::i);
+
return 0;
}
diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp b/gdb/testsuite/gdb.cp/cpexprs.exp
index 13af265..eda5d5a 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.exp
+++ b/gdb/testsuite/gdb.cp/cpexprs.exp
@@ -719,5 +719,26 @@ foreach name [get_functions list] {
}
}
+# Test c/v gets recognized even without quoting.
+foreach cv {{} { const} { volatile} { const volatile}} {
+ set test "p 'CV::m(int)$cv'"
+ gdb_test_multiple $test $test {
+ -re "( = {.*} 0x\[0-9a-f\]+ <CV::m.*>)\r\n$gdb_prompt $" {
+ # = {void (CV * const, CV::t)} 0x400944 <CV::m(int)>
+ set correct $expect_out(1,string)
+ pass $test
+ }
+ }
+ if {"$cv" != ""} {
+ setup_kfail c++/14186 *-*-*
+ }
+ gdb_test "p CV::m(int)$cv" [string_to_regexp $correct]
+}
+
+# Test TYPENAME:: gets recognized even in parentheses.
+gdb_test "p CV_f(int)" { = {int \(int\)} 0x40097b <CV_f\(int\)>}
+gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x40097b <CV_f\(int\)>}
+gdb_test "p CV_f(CV::i)" " = 43"
+
gdb_exit
return 0