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]

[incremental] Patch: FYI: decl-smashing fixes


I'm checking this in on the incremental-compiler branch.

Last week I noticed a major logic error in the decl-smashing-avoidance
code.  Whoops.  This patch fixes this problem and then tweaks a number
of places to adapt.

There are still some problems resulting from this patch, but nothing
too major, I think.  With this patch the incremental compiler can
compile more things than before, so that's good.  For instance now it
can compile most of the C front end in incremental mode.

Tom

ChangeLog:
2007-12-11  Tom Tromey  <tromey@redhat.com>

	* c-typeck.c (require_complete_type): Now static.
	(build_function_call): Cast function type.
	(comptypes_internal): Use smashed type variant.
	(build_indirect_ref): Convert pointer type, not type of
	dereference.
	(really_start_incremental_init): Use smashed type variant.
	* c-tree.h (require_complete_type): Remove declaration.
	(C_SMASHED_TYPE_VARIANT): Rewrote.
	(C_SMASHED_VARIANT): Remove.
	* c-decl.c (grokdeclarator): Remove unused variable.
	(start_struct): Fix condition.
	(start_enum): Likewise.
	(declspecs_add_type): Use smashed variant of a typedef.
	(duplicate_decls): Use smashed type variant.
	(pushdecl): Likewise.

Index: c-tree.h
===================================================================
--- c-tree.h	(revision 130473)
+++ c-tree.h	(working copy)
@@ -457,15 +457,13 @@
 /* True if this decl or type has been smashed.  */
 #define C_SMASHED_P(T) TREE_LANG_FLAG_5 (T)
 
-/* Return the smashed decl or type corresponding to ARG.  If ARG is
-   not smashed, return ARG.  */
-#define C_SMASHED_VARIANT(ARG) \
-  (((ARG) && C_SMASHED_P (ARG)) ? c_parser_find_binding (ARG) : (ARG))
-
 /* Return the smashed variant of TYPE.  This will look up the
    canonical type if it exists.  FIXME: better comment here.  */
-#define C_SMASHED_TYPE_VARIANT(TYPE) \
-  C_SMASHED_VARIANT ((TYPE_CANONICAL (TYPE)) ? (TYPE_CANONICAL (TYPE)) : (TYPE))
+#define C_SMASHED_TYPE_VARIANT(TYPE)					\
+  (C_SMASHED_P (TYPE_MAIN_VARIANT (TYPE))				\
+   ? build_qualified_type (c_parser_find_binding (TYPE_MAIN_VARIANT (TYPE)), \
+			   TYPE_QUALS (TYPE))				\
+   : TYPE)
 
 /* in c-aux-info.c */
 extern void gen_aux_info_record (tree, int, int, int);
@@ -570,7 +568,6 @@
 extern struct c_label_context_se *label_context_stack_se;
 extern struct c_label_context_vm *label_context_stack_vm;
 
-extern tree require_complete_type (tree);
 extern int same_translation_unit_p (tree, tree);
 extern int comptypes (tree, tree);
 extern bool c_vla_type_p (const_tree);
Index: c-decl.c
===================================================================
--- c-decl.c	(revision 130607)
+++ c-decl.c	(working copy)
@@ -2121,7 +2121,8 @@
 	  /* FIXME: we shouldn't need a copy -- we should just modify
 	     NEWDECL.  */
 	  tree copy = copy_node (olddecl);
-	  merge_decls (newdecl, copy, newtype, oldtype);
+	  merge_decls (newdecl, copy, newtype,
+		       C_SMASHED_TYPE_VARIANT (oldtype));
 	  /* FIXME: this triggers building libgcc.  */
 /* 	  gcc_assert (binding->decl == olddecl); */
 	  binding->decl = copy;
@@ -2338,6 +2339,7 @@
 		thistype = composite_type (vistype, type);
 	      else
 		thistype = TREE_TYPE (b_use->decl);
+	      thistype = C_SMASHED_TYPE_VARIANT (thistype);
 	      b_use->type = TREE_TYPE (b_use->decl);
 	      if (TREE_CODE (b_use->decl) == FUNCTION_DECL
 		  && DECL_BUILT_IN (b_use->decl))
@@ -4265,7 +4267,6 @@
   int volatilep;
   int type_quals = TYPE_UNQUALIFIED;
   const char *name, *orig_name;
-  tree typedef_type = 0;
   bool funcdef_flag = false;
   bool funcdef_syntax = false;
   int size_varies = 0;
@@ -4339,7 +4340,6 @@
       type = integer_type_node;
     }
 
-  typedef_type = type;
   size_varies = C_TYPE_VARIABLE_SIZE (type);
 
   /* Diagnose defaulting to "int".  */
@@ -5656,10 +5656,12 @@
 	}
     }
 
-  /* Otherwise create a forward-reference just so the tag is in scope.  */
-
-  if (ref == NULL_TREE || (TREE_CODE (ref) != code
-			   && !object_in_current_hunk_p (ref)))
+  /* Otherwise create a forward-reference just so the tag is in scope.
+     Also make a reference if we found the wrong type of object, or if
+     the one we found is in a different hunk and thus should not be
+     smashed.  */
+  if (ref == NULL_TREE || TREE_CODE (ref) != code
+      || !object_in_current_hunk_p (ref))
     {
       tree newval = make_node (code);
       pushtag (name, newval);
@@ -6110,8 +6112,8 @@
 	}
     }
 
-  if (enumtype == 0 || (TREE_CODE (enumtype) != ENUMERAL_TYPE
-			&& !object_in_current_hunk_p (enumtype)))
+  if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE
+      || !object_in_current_hunk_p (enumtype))
     {
       tree newval = make_node (ENUMERAL_TYPE);
       pushtag (name, newval);
@@ -7803,7 +7805,7 @@
 	; /* Allow the type to default to int to avoid cascading errors.  */
       else
 	{
-	  specs->type = TREE_TYPE (type);
+	  specs->type = C_SMASHED_TYPE_VARIANT (TREE_TYPE (type));
 	  specs->decl_attr = DECL_ATTRIBUTES (type);
 	  specs->typedef_p = true;
 	  specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 130053)
+++ c-typeck.c	(working copy)
@@ -140,7 +140,7 @@
 /* Do `exp = require_complete_type (exp);' to make sure exp
    does not have an incomplete type.  (That includes void types.)  */
 
-tree
+static tree
 require_complete_type (tree value)
 {
   tree type = TREE_TYPE (value);
@@ -794,6 +794,9 @@
       || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
     return 1;
 
+  t1 = C_SMASHED_TYPE_VARIANT (t1);
+  t2 = C_SMASHED_TYPE_VARIANT (t2);
+
   /* If either type is the internal version of sizetype, return the
      language version.  */
   if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
@@ -1906,17 +1909,19 @@
       else
 	{
 	  tree t = TREE_TYPE (type);
-	  tree ref, t2;
+	  tree ref, t2 = C_SMASHED_TYPE_VARIANT (t);
 
-	  ref = build1 (INDIRECT_REF, t, pointer);
-
-	  t2 = C_SMASHED_TYPE_VARIANT (t);
 	  if (t != t2)
 	    {
-	      ref = build1 (VIEW_CONVERT_EXPR, t2, ref);
+	      int sf = TREE_SIDE_EFFECTS (pointer);
+	      pointer = build1 (VIEW_CONVERT_EXPR, build_pointer_type (t2),
+				pointer);
+	      TREE_SIDE_EFFECTS (pointer) = sf;
 	      t = t2;
 	    }
 
+	  ref = build1 (INDIRECT_REF, t, pointer);
+
 	  if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
 	    {
 	      error ("dereferencing pointer to incomplete type");
@@ -2350,6 +2355,17 @@
 	}
     }
 
+  if (C_SMASHED_TYPE_VARIANT (TREE_TYPE (fntype)) != TREE_TYPE (fntype))
+    {
+      /* The function returns a type that was later completed.  Cast
+	 the function to the smashed type.  */
+      tree copy = copy_node (fntype);
+      TREE_TYPE (copy) = C_SMASHED_TYPE_VARIANT (TREE_TYPE (copy));
+      function = build1 (VIEW_CONVERT_EXPR, build_pointer_type (copy),
+			 function);
+      fntype = copy;
+    }
+
   /* Convert the parameters to the types declared in the
      function prototype, or apply default promotions.  */
 
@@ -5068,6 +5084,7 @@
 
   if (type == 0)
     type = TREE_TYPE (constructor_decl);
+  type = C_SMASHED_TYPE_VARIANT (type);
 
   if (targetm.vector_opaque_p (type))
     error ("opaque vector types cannot be initialized");


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