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: PR 29226


This patch fixes PR c++/29226, a crash involving templates and VLAs.
The problem here is that we tried to evaluate a sizeof(VLA) expression
in an uninstantiated template, which lead to a SAVE_EXPR containing a
reference to one of the function parameters to the uninstantiated
template.  The template substitution machinery (rightfully) never
expects to see a SAVE_EXPR, and so doesn't burrow inside it to
substitute the function parameter for the instantiation for the
function parameter for the template, leading to the ICE.  If we run
into a VLA in a sizeof expression in a template, we needn't worry
about the value; it's not an integral-constant expression, so we can
defer it until instantiation.

Tested on x86_64-unknown-linux-gnu, applied on the mainline.  Will
apply to the 4.1 branch, once testing completes.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2006-10-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/29226
	* typeck.c (cxx_sizeof_or_alignof_type): Tidy.  In templates, do
	not try to actually evaluate sizeof for a VLA type.

2006-10-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/29226
	* g++.dg/template/vla1.C: New test.

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 117359)
+++ gcc/cp/typeck.c	(working copy)
@@ -1241,38 +1241,39 @@ compparms (tree parms1, tree parms2)
 tree
 cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
 {
-  enum tree_code type_code;
   tree value;
-  const char *op_name;
 
   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
   if (type == error_mark_node)
     return error_mark_node;
 
-  if (dependent_type_p (type))
-    {
-      value = build_min (op, size_type_node, type);
-      TREE_READONLY (value) = 1;
-      return value;
-    }
-
-  op_name = operator_name_info[(int) op].name;
-
   type = non_reference (type);
-  type_code = TREE_CODE (type);
-
-  if (type_code == METHOD_TYPE)
+  if (TREE_CODE (type) == METHOD_TYPE)
     {
       if (complain && (pedantic || warn_pointer_arith))
-	pedwarn ("invalid application of %qs to a member function", op_name);
+	pedwarn ("invalid application of %qs to a member function", 
+		 operator_name_info[(int) op].name);
       value = size_one_node;
     }
-  else
-    value = c_sizeof_or_alignof_type (complete_type (type),
-				      op == SIZEOF_EXPR,
-				      complain);
 
-  return value;
+  if (dependent_type_p (type)
+      /* VLA types will have a non-constant size.  In the body of an
+	 uninstantiated template, we don't need to try to compute the
+	 value, because the sizeof expression is not an integral
+	 constant expression in that case.  And, if we do try to
+	 compute the value, we'll likely end up with SAVE_EXPRs, which
+	 the template substitution machinery does not expect to see.  */
+      || (processing_template_decl && 
+	  TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
+    {
+      value = build_min (op, size_type_node, type);
+      TREE_READONLY (value) = 1;
+      return value;
+    }
+
+  return c_sizeof_or_alignof_type (complete_type (type),
+				   op == SIZEOF_EXPR,
+				   complain);
 }
 
 /* Process a sizeof expression where the operand is an expression.  */
Index: gcc/testsuite/g++.dg/template/vla1.C
===================================================================
--- gcc/testsuite/g++.dg/template/vla1.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/vla1.C	(revision 0)
@@ -0,0 +1,9 @@
+// PR c++/29226
+// { dg-options "" }
+
+template <bool>
+static int label (int w)
+{
+  sizeof(int[w]);
+}
+int a = label<false>(1);


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