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]

[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


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