This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[incremental] Patch: FYI: decl-smashing fixes
- From: Tom Tromey <tromey at redhat dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 11 Dec 2007 11:32:22 -0700
- Subject: [incremental] Patch: FYI: decl-smashing fixes
- Reply-to: tromey at redhat dot com
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");