This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[C++ PATCH] Fix cp_parser_direct_declarator (PR c++/29886)


Hi!

cp_parser_direct_declarator is used even in tentative parsing, but
is unconditionally issuing error, which breaks the attached testcase.
I don't see any machiner in cp/parser.c which would allow to queue
non-parsing errors and emit them only when we definitely commit
to parse it.  The following patch instead moves the diagnostic
emitting to grokdeclarator.  As array.bounds == NULL_TREE is used for
[] arrays and there might be other reason why error_mark_node would be
stored in array.bounds, I chose just to stick a pointer to the error
message string into an otherwise unused padding in struct cp_declarator
(u.array is smaller than other union fields) instead of always emitting
a hardcoded error message when array.bounds == error_mark_node
or coming up with another special value for array.bounds.
As explained elsewhere in parser.c, we need to record somewhere
whether the array bounds were non_constant_p or not, that information
can't be deduced from whether bounds is INTEGER_CST or not.

Ok for 4.1/4.2/4.3?

2006-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR c++/29886
	* cp-tree.h (struct cp_declarator): Add array.error_msg field.
	* parser.c: Include intl.h.
	(make_array_declarator): Add error_msg argument, set array.error_msg.
	(cp_parser_direct_new_declarator): Adjust caller.
	(cp_parser_direct_declarator): Instead of issuing error message about
	non-constant bounds pass the error message string to
	make_array_declarator.
	* decl.c (grokdeclarator): If array.error_msg is non-NULL, issue
	diagnostics.
	* Makefile.in (cp/parser.o): Depend on intl.h.

	* g++.dg/parse/array1.C: New test.

--- gcc/cp/cp-tree.h.jj	2006-11-23 10:23:51.000000000 +0100
+++ gcc/cp/cp-tree.h	2006-11-23 16:08:52.000000000 +0100
@@ -3762,6 +3762,9 @@ struct cp_declarator {
     struct {
       /* The bounds to the array.  */
       tree bounds;
+      /* Error message about array bounds that should be emitted if
+	 non-NULL.  */
+      const char *error_msg;
     } array;
     /* For cdk_pointer, cdk_reference, and cdk_ptrmem.  */
     struct {
--- gcc/cp/parser.c.jj	2006-11-23 10:23:51.000000000 +0100
+++ gcc/cp/parser.c	2006-11-23 16:23:37.000000000 +0100
@@ -38,6 +38,7 @@
 #include "target.h"
 #include "cgraph.h"
 #include "c-common.h"
+#include "intl.h"
 
 
 /* The lexer.  */
@@ -820,7 +821,7 @@ clear_decl_specs (cp_decl_specifier_seq 
 static cp_declarator *make_call_declarator
   (cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree);
 static cp_declarator *make_array_declarator
-  (cp_declarator *, tree);
+  (cp_declarator *, tree, const char *);
 static cp_declarator *make_pointer_declarator
   (cp_cv_quals, cp_declarator *);
 static cp_declarator *make_reference_declarator
@@ -970,16 +971,19 @@ make_call_declarator (cp_declarator *tar
 }
 
 /* Make a declarator for an array of BOUNDS elements, each of which is
-   defined by ELEMENT.  */
+   defined by ELEMENT.  ERROR_MSG is an error message that should be
+   emitted if any when creating the trees.  */
 
 cp_declarator *
-make_array_declarator (cp_declarator *element, tree bounds)
+make_array_declarator (cp_declarator *element, tree bounds,
+		       const char *error_msg)
 {
   cp_declarator *declarator;
 
   declarator = make_declarator (cdk_array);
   declarator->declarator = element;
   declarator->u.array.bounds = bounds;
+  declarator->u.array.error_msg = error_msg;
 
   return declarator;
 }
@@ -5399,7 +5403,7 @@ cp_parser_direct_new_declarator (cp_pars
       cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
 
       /* Add this bound to the declarator.  */
-      declarator = make_array_declarator (declarator, expression);
+      declarator = make_array_declarator (declarator, expression, NULL);
 
       /* If the next token is not a `[', then there are no more
 	 bounds.  */
@@ -11672,6 +11676,7 @@ cp_parser_direct_declarator (cp_parser* 
 	{
 	  /* Parse an array-declarator.  */
 	  tree bounds;
+	  const char *error_msg = NULL;
 
 	  if (ctor_dtor_or_conv_p)
 	    *ctor_dtor_or_conv_p = 0;
@@ -11700,7 +11705,7 @@ cp_parser_direct_declarator (cp_parser* 
 		 in function scopes.  */
 	      else if (!at_function_scope_p ())
 		{
-		  error ("array bound is not an integer constant");
+		  error_msg = N_("array bound is not an integer constant");
 		  bounds = error_mark_node;
 		}
 	    }
@@ -11713,7 +11718,7 @@ cp_parser_direct_declarator (cp_parser* 
 	      break;
 	    }
 
-	  declarator = make_array_declarator (declarator, bounds);
+	  declarator = make_array_declarator (declarator, bounds, error_msg);
 	}
       else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
 	{
--- gcc/cp/decl.c.jj	2006-11-23 10:23:51.000000000 +0100
+++ gcc/cp/decl.c	2006-11-23 16:22:58.000000000 +0100
@@ -7525,6 +7525,8 @@ grokdeclarator (const cp_declarator *dec
       switch (declarator->kind)
 	{
 	case cdk_array:
+	  if (declarator->u.array.error_msg)
+	    error (declarator->u.array.error_msg);
 	  type = create_array_type_for_decl (dname, type,
 					     declarator->u.array.bounds);
 	  break;
--- gcc/cp/Make-lang.in.jj	2006-11-20 21:11:41.000000000 +0100
+++ gcc/cp/Make-lang.in	2006-11-20 21:11:41.000000000 +0100
@@ -287,7 +287,7 @@ cp/optimize.o: cp/optimize.c $(CXX_TREE_
 cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
   gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
 cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
-  output.h $(TARGET_H)
+  output.h $(TARGET_H) intl.h
 cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h $(C_COMMON_H) \
 	$(TM_H) coretypes.h pointer-set.h
 
--- gcc/testsuite/g++.dg/parse/array1.C.jj	2006-11-23 16:36:07.000000000 +0100
+++ gcc/testsuite/g++.dg/parse/array1.C	2006-11-23 16:34:53.000000000 +0100
@@ -0,0 +1,24 @@
+// PR c++/29886
+// { dg-do compile }
+
+struct A
+{
+  static int x[2];
+};
+int y[2];
+struct B
+{
+  static int z[2];
+};
+int A::z[(3, 2)];	// { dg-error "array bound is not an integer constant" }
+
+void
+foo (int i)
+{
+  int j = int (A::x[i]);
+  switch (int (A::x[i])) {}
+  if (int (A::x[i])) {}
+  j = int (y[i]);
+  switch (int (y[i])) {}
+  if (int (y[i])) {}
+}

	Jakub


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