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 for array index sfinae


I noticed people on irc talking about Onay's recent mail to gcc-help (http://gcc.gnu.org/ml/gcc-help/2010-05/msg00118.html) and decided to go ahead and fix the bug. A straightforward case of not passing complain down far enough.

Tested x86_64-pc-linux-gnu, applied to trunk.

commit 802a28aafe5a6705ca15e938fb067a3fa30666d6
Author: Jason Merrill <jason@redhat.com>
Date:   Wed May 12 21:44:54 2010 -0400

    	* typeck.c (build_array_ref): Take complain parm.
    	* cp-tree.h: Add it to prototype.
    	* call.c (build_new_op): Pass it.
    	* class.c (build_vtbl_ref): Pass it.
    	* decl2.c (grok_array_decl): Pass it.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0f62059..5f8aeea 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4517,7 +4517,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       return cp_build_unary_op (code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
-      return build_array_ref (input_location, arg1, arg2);
+      return build_array_ref (input_location, arg1, arg2, complain);
 
     case MEMBER_REF:
       return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, 
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 88db80f..e22ef07 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -629,7 +629,7 @@ build_vtbl_ref_1 (tree instance, tree idx)
   if (!vtbl)
     vtbl = build_vfield_ref (instance, basetype);
 
-  aref = build_array_ref (input_location, vtbl, idx);
+  aref = build_array_ref (input_location, vtbl, idx, tf_warning_or_error);
   TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
 
   return aref;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 02e81eb..a9dc616 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5365,7 +5365,8 @@ extern tree build_x_indirect_ref		(tree, ref_operator,
                                                  tsubst_flags_t);
 extern tree cp_build_indirect_ref		(tree, ref_operator,
                                                  tsubst_flags_t);
-extern tree build_array_ref			(location_t, tree, tree);
+extern tree build_array_ref			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree get_member_function_from_ptrfunc	(tree *, tree);
 extern tree cp_build_function_call              (tree, tree, tsubst_flags_t);
 extern tree cp_build_function_call_vec		(tree, VEC(tree,gc) **,
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index d811c9e..ae7c2ab 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -399,7 +399,8 @@ grok_array_decl (tree array_expr, tree index_exp)
       if (array_expr == error_mark_node || index_exp == error_mark_node)
 	error ("ambiguous conversion for array subscript");
 
-      expr = build_array_ref (input_location, array_expr, index_exp);
+      expr = build_array_ref (input_location, array_expr, index_exp,
+			      tf_warning_or_error);
     }
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 0ff8573..91aaafe 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2860,13 +2860,15 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
    LOC is the location to use in building the array reference.  */
 
 tree
-build_array_ref (location_t loc, tree array, tree idx)
+build_array_ref (location_t loc, tree array, tree idx,
+		 tsubst_flags_t complain)
 {
   tree ret;
 
   if (idx == 0)
     {
-      error_at (loc, "subscript missing in array reference");
+      if (complain & tf_error)
+	error_at (loc, "subscript missing in array reference");
       return error_mark_node;
     }
 
@@ -2880,7 +2882,8 @@ build_array_ref (location_t loc, tree array, tree idx)
     {
     case COMPOUND_EXPR:
       {
-	tree value = build_array_ref (loc, TREE_OPERAND (array, 1), idx);
+	tree value = build_array_ref (loc, TREE_OPERAND (array, 1), idx,
+				      complain);
 	ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
 		      TREE_OPERAND (array, 0), value);
 	SET_EXPR_LOCATION (ret, loc);
@@ -2890,8 +2893,8 @@ build_array_ref (location_t loc, tree array, tree idx)
     case COND_EXPR:
       ret = build_conditional_expr
 	      (TREE_OPERAND (array, 0),
-	       build_array_ref (loc, TREE_OPERAND (array, 1), idx),
-	       build_array_ref (loc, TREE_OPERAND (array, 2), idx),
+	       build_array_ref (loc, TREE_OPERAND (array, 1), idx, complain),
+	       build_array_ref (loc, TREE_OPERAND (array, 2), idx, complain),
 	       tf_warning_or_error);
       protected_set_expr_location (ret, loc);
       return ret;
@@ -2908,7 +2911,8 @@ build_array_ref (location_t loc, tree array, tree idx)
 
       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
 	{
-	  error_at (loc, "array subscript is not an integer");
+	  if (complain & tf_error)
+	    error_at (loc, "array subscript is not an integer");
 	  return error_mark_node;
 	}
 
@@ -2944,7 +2948,7 @@ build_array_ref (location_t loc, tree array, tree idx)
 	    return error_mark_node;
 	}
 
-      if (!lvalue_p (array))
+      if (!lvalue_p (array) && (complain & tf_error))
 	pedwarn (loc, OPT_pedantic, 
 	         "ISO C++ forbids subscripting non-lvalue array");
 
@@ -2956,7 +2960,8 @@ build_array_ref (location_t loc, tree array, tree idx)
 	  tree foo = array;
 	  while (TREE_CODE (foo) == COMPONENT_REF)
 	    foo = TREE_OPERAND (foo, 0);
-	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
+	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)
+	      && (complain & tf_warning))
 	    warning_at (loc, OPT_Wextra,
 			"subscripting array declared %<register%>");
 	}
@@ -2993,12 +2998,14 @@ build_array_ref (location_t loc, tree array, tree idx)
 
     if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE)
       {
-	error_at (loc, "subscripted value is neither array nor pointer");
+	if (complain & tf_error)
+	  error_at (loc, "subscripted value is neither array nor pointer");
 	return error_mark_node;
       }
     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
       {
-	error_at (loc, "array subscript is not an integer");
+	if (complain & tf_error)
+	  error_at (loc, "array subscript is not an integer");
 	return error_mark_node;
       }
 
@@ -3006,9 +3013,9 @@ build_array_ref (location_t loc, tree array, tree idx)
 
     ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
 						     PLUS_EXPR, ar, ind,
-						     tf_warning_or_error),
+						     complain),
                                  RO_ARRAY_INDEXING,
-                                 tf_warning_or_error);
+                                 complain);
     protected_set_expr_location (ret, loc);
     return ret;
   }
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae1.C b/gcc/testsuite/g++.dg/cpp0x/sfinae1.C
new file mode 100644
index 0000000..292d8ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae1.C
@@ -0,0 +1,11 @@
+// { dg-options "-std=c++0x" }
+
+template< typename T_VECTOR >
+void f(const T_VECTOR &a, decltype(a[0]) t = 0);
+template< typename T >
+void f(const T &a, decltype(a*1) t = 0);
+
+int main() {
+  int c;
+  f(c);
+}

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