public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH to oversized array handling
@ 2018-05-11 23:09 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2018-05-11 23:09 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 228 bytes --]

We weren't checking for arrays being too large in tsubst, which meant
that we don't catch that problem as early as we would like.  Fixed by
calling valid_array_size_p from tsubst.

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

[-- Attachment #2: valid-array.diff --]
[-- Type: text/x-patch, Size: 4191 bytes --]

commit eba9af072d35ec8cc0840622e30a096401d306fb
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Mar 16 11:55:54 2018 -0400

            * pt.c (tsubst) [ARRAY_TYPE]: Check valid_array_size_p.
    
            (tsubst_copy_and_build) [NEW_EXPR]: Clear in_decl.
    
    gcc/c-family/
            * c-common.c (valid_array_size_p): Add complain parameter.
            * c-common.h: ...which defaults to true.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index e8bb3eb23f8..859eeb47252 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7872,17 +7872,20 @@ reject_gcc_builtin (const_tree expr, location_t loc /* = UNKNOWN_LOCATION */)
    the name of the array, or NULL_TREE for unnamed arrays.  */
 
 bool
-valid_array_size_p (location_t loc, tree type, tree name)
+valid_array_size_p (location_t loc, tree type, tree name, bool complain)
 {
   if (type != error_mark_node
       && COMPLETE_TYPE_P (type)
       && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
       && !valid_constant_size_p (TYPE_SIZE_UNIT (type)))
     {
-      if (name)
-	error_at (loc, "size of array %qE is too large", name);
-      else
-	error_at (loc, "size of unnamed array is too large");
+      if (complain)
+	{
+	  if (name)
+	    error_at (loc, "size of array %qE is too large", name);
+	  else
+	    error_at (loc, "size of unnamed array is too large");
+	}
       return false;
     }
   return true;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index f2c66628e53..c266fee74c7 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1248,7 +1248,7 @@ extern tree find_inv_trees (tree *, int *, void *);
 extern tree replace_inv_trees (tree *, int *, void *);
 
 extern bool reject_gcc_builtin (const_tree, location_t = UNKNOWN_LOCATION);
-extern bool valid_array_size_p (location_t, tree, tree);
+extern bool valid_array_size_p (location_t, tree, tree, bool = true);
 
 /* In c-warn.c.  */
 extern void constant_expression_warning (tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 790d6ea25e9..cd9011b1b61 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14788,6 +14788,10 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
 	r = build_cplus_array_type (type, domain);
 
+	if (!valid_array_size_p (input_location, r, in_decl,
+				 (complain & tf_error)))
+	  return error_mark_node;
+
 	if (TYPE_USER_ALIGN (t))
 	  {
 	    SET_TYPE_ALIGN (r, TYPE_ALIGN (t));
@@ -18147,6 +18151,9 @@ tsubst_copy_and_build (tree t,
 	      }
 	  }
 
+	/* Avoid passing an enclosing decl to valid_array_size_p.  */
+	in_decl = NULL_TREE;
+
 	tree op1 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
 	tree op2 = RECUR (TREE_OPERAND (t, 2));
 	ret = build_new (&placement_vec, op1, op2, &init_vec,
diff --git a/gcc/testsuite/g++.dg/init/new38.C b/gcc/testsuite/g++.dg/init/new38.C
index 37da525bf78..a03e231cbfe 100644
--- a/gcc/testsuite/g++.dg/init/new38.C
+++ b/gcc/testsuite/g++.dg/init/new38.C
@@ -22,7 +22,7 @@ template <typename T>
 void
 large_array_template1(int n)
 {
-  new T[n] // { dg-error "size of array is too large" }
+  new T[n] // { dg-error "size of unnamed array is too large" }
     [(1ULL << (sizeof(void *) * 4)) / sizeof(T)]
     [1ULL << (sizeof(void *) * 4)];
 }
@@ -31,7 +31,7 @@ template <typename T>
 void
 large_array_template2(int n)
 {
-  new T[n] // { dg-error "size of array is too large" }
+  new T[n] // { dg-error "size of unnamed array is too large" }
     [(1ULL << (sizeof(void *) * 4)) / sizeof(T)]
     [1ULL << (sizeof(void *) * 4)];
 }
@@ -40,7 +40,7 @@ template <typename T>
 void
 large_array_template3(int n)
 {
-  new T[n] // { dg-error "size of array is too large" }
+  new T[n] // { dg-error "size of unnamed array is too large" }
     [(1ULL << (sizeof(void *) * 4)) / sizeof(T)]
     [1ULL << (sizeof(void *) * 4)];
 }
diff --git a/gcc/testsuite/g++.dg/template/array30.C b/gcc/testsuite/g++.dg/template/array30.C
new file mode 100644
index 00000000000..3608c2e1233
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array30.C
@@ -0,0 +1,7 @@
+template <int I>
+struct A
+{
+  int ar[I][I][I][I][I][I][I][I][I][I]; // { dg-error "too large" }
+};
+
+A<66000> a;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-05-11 21:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-11 23:09 C++ PATCH to oversized array handling Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).