aboutsummaryrefslogtreecommitdiff
path: root/gnu/usr.bin/cc/cc1
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>1994-11-03 06:52:42 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>1994-11-03 06:52:42 +0000
commitfe7dee47009525e334f1bde385b69753f007085c (patch)
tree50f1f9fa63ff73191f024d12c1c848e9cdcf55f8 /gnu/usr.bin/cc/cc1
parente0115bffa0ca4536902354411d53074e91a944ff (diff)
Notes
Diffstat (limited to 'gnu/usr.bin/cc/cc1')
-rw-r--r--gnu/usr.bin/cc/cc1/c-decl.c71
-rw-r--r--gnu/usr.bin/cc/cc1/c-parse.c49
-rw-r--r--gnu/usr.bin/cc/cc1/c-typeck.c120
3 files changed, 136 insertions, 104 deletions
diff --git a/gnu/usr.bin/cc/cc1/c-decl.c b/gnu/usr.bin/cc/cc1/c-decl.c
index c1a8dc99393e..995009a46354 100644
--- a/gnu/usr.bin/cc/cc1/c-decl.c
+++ b/gnu/usr.bin/cc/cc1/c-decl.c
@@ -1303,6 +1303,7 @@ duplicate_decls (newdecl, olddecl)
&& DECL_INITIAL (newdecl) != 0);
tree oldtype = TREE_TYPE (olddecl);
tree newtype = TREE_TYPE (newdecl);
+ char *errmsg = 0;
if (TREE_CODE (newtype) == ERROR_MARK
|| TREE_CODE (oldtype) == ERROR_MARK)
@@ -1528,7 +1529,7 @@ duplicate_decls (newdecl, olddecl)
}
else
{
- char *errmsg = redeclaration_error_message (newdecl, olddecl);
+ errmsg = redeclaration_error_message (newdecl, olddecl);
if (errmsg)
{
error_with_decl (newdecl, errmsg);
@@ -1625,7 +1626,7 @@ duplicate_decls (newdecl, olddecl)
}
/* Optionally warn about more than one declaration for the same name. */
- if (warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
+ if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
/* Dont warn about a function declaration
followed by a definition. */
&& !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0
@@ -2439,6 +2440,21 @@ shadow_label (name)
if (decl != 0)
{
+ register tree dup;
+
+ /* Check to make sure that the label hasn't already been declared
+ at this label scope */
+ for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
+ if (TREE_VALUE (dup) == decl)
+ {
+ error ("duplicate label declaration `%s'",
+ IDENTIFIER_POINTER (name));
+ error_with_decl (TREE_VALUE (dup),
+ "this is a previous declaration");
+ /* Just use the previous declaration. */
+ return lookup_label (name);
+ }
+
shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
IDENTIFIER_LABEL_VALUE (name) = decl = 0;
}
@@ -3673,7 +3689,7 @@ finish_decl (decl, init, asmspec_tree)
references to it. */
/* This test used to include TREE_STATIC, but this won't be set
for function level initializers. */
- if (TREE_READONLY (decl))
+ if (TREE_READONLY (decl) || ITERATOR_P (decl))
{
preserve_initializer ();
/* Hack? Set the permanent bit for something that is permanent,
@@ -5418,7 +5434,7 @@ finish_struct (t, fieldlist)
#endif
}
}
- else
+ else if (TREE_TYPE (x) != error_mark_node)
{
int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
: TYPE_ALIGN (TREE_TYPE (x)));
@@ -5646,37 +5662,6 @@ start_enum (name)
return enumtype;
}
-/* Return the minimum number of bits needed to represent VALUE in a
- signed or unsigned type, UNSIGNEDP says which. */
-
-static int
-min_precision (value, unsignedp)
- tree value;
- int unsignedp;
-{
- int log;
-
- /* If the value is negative, compute its negative minus 1. The latter
- adjustment is because the absolute value of the largest negative value
- is one larger than the largest positive value. This is equivalent to
- a bit-wise negation, so use that operation instead. */
-
- if (tree_int_cst_sgn (value) < 0)
- value = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (value), value));
-
- /* Return the number of bits needed, taking into account the fact
- that we need one more bit for a signed than unsigned type. */
-
- if (integer_zerop (value))
- log = 0;
- else if (TREE_INT_CST_HIGH (value) != 0)
- log = HOST_BITS_PER_WIDE_INT + floor_log2 (TREE_INT_CST_HIGH (value));
- else
- log = floor_log2 (TREE_INT_CST_LOW (value));
-
- return log + 1 + ! unsignedp;
-}
-
/* After processing and defining all the values of an enumeration type,
install their decls in the enumeration type and finish it off.
ENUMTYPE is the type object and VALUES a list of decl-value pairs.
@@ -5868,6 +5853,7 @@ start_function (declspecs, declarator, nested)
{
tree decl1, old_decl;
tree restype;
+ int old_immediate_size_expand = immediate_size_expand;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -5877,6 +5863,9 @@ start_function (declspecs, declarator, nested)
named_labels = 0;
shadowed_labels = 0;
+ /* Don't expand any sizes in the return type of the function. */
+ immediate_size_expand = 0;
+
decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
/* If the declarator is not suitable for a function definition,
@@ -5922,6 +5911,11 @@ start_function (declspecs, declarator, nested)
current_function_prototype_line = DECL_SOURCE_LINE (old_decl);
}
+ /* If there is no explicit declaration, look for any out-of-scope implicit
+ declarations. */
+ if (old_decl == 0)
+ old_decl = IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1));
+
/* Optionally warn of old-fashioned def with no previous prototype. */
if (warn_strict_prototypes
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
@@ -5937,7 +5931,7 @@ start_function (declspecs, declarator, nested)
if the function has already been used. */
else if (warn_missing_prototypes
&& old_decl != 0 && TREE_USED (old_decl)
- && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0))
+ && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
warning_with_decl (decl1,
"`%s' was used with no prototype before its definition");
/* Optionally warn of any global def with no previous declaration. */
@@ -5949,7 +5943,8 @@ start_function (declspecs, declarator, nested)
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
else if (warn_missing_declarations
- && old_decl != 0 && TREE_USED (old_decl))
+ && old_decl != 0 && TREE_USED (old_decl)
+ && old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
warning_with_decl (decl1,
"`%s' was used with no declaration before its definition");
@@ -6006,6 +6001,8 @@ start_function (declspecs, declarator, nested)
if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
TREE_ADDRESSABLE (current_function_decl) = 1;
+ immediate_size_expand = old_immediate_size_expand;
+
return 1;
}
diff --git a/gnu/usr.bin/cc/cc1/c-parse.c b/gnu/usr.bin/cc/cc1/c-parse.c
index 5120144ad412..8a6465cb397d 100644
--- a/gnu/usr.bin/cc/cc1/c-parse.c
+++ b/gnu/usr.bin/cc/cc1/c-parse.c
@@ -395,9 +395,9 @@ static const short yyrline[] = { 0,
1576, 1585, 1590, 1595, 1600, 1604, 1608, 1619, 1626, 1633,
1640, 1651, 1655, 1658, 1663, 1686, 1720, 1745, 1774, 1789,
1800, 1804, 1808, 1811, 1816, 1818, 1821, 1823, 1827, 1832,
- 1835, 1841, 1846, 1851, 1853, 1862, 1863, 1869, 1871, 1876,
- 1878, 1882, 1885, 1891, 1894, 1896, 1898, 1900, 1907, 1912,
- 1917, 1919, 1928, 1931, 1936, 1939
+ 1835, 1841, 1846, 1851, 1853, 1862, 1863, 1869, 1871, 1881,
+ 1883, 1887, 1890, 1896, 1899, 1901, 1903, 1905, 1912, 1917,
+ 1922, 1924, 1933, 1936, 1941, 1944
};
static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER",
@@ -3252,60 +3252,65 @@ case 348:
case 349:
#line 1872 "c-parse.y"
{ yyval.ttype = get_parm_info (0);
- if (pedantic)
- pedwarn ("ANSI C requires a named argument before `...'");
+ /* Gcc used to allow this as an extension. However, it does
+ not work for all targets, and thus has been disabled.
+ Also, since func (...) and func () are indistinguishable,
+ it caused problems with the code in expand_builtin which
+ tries to verify that BUILT_IN_NEXT_ARG is being used
+ correctly. */
+ error ("ANSI C requires a named argument before `...'");
;
break;}
case 350:
-#line 1877 "c-parse.y"
+#line 1882 "c-parse.y"
{ yyval.ttype = get_parm_info (1); ;
break;}
case 351:
-#line 1879 "c-parse.y"
+#line 1884 "c-parse.y"
{ yyval.ttype = get_parm_info (0); ;
break;}
case 352:
-#line 1884 "c-parse.y"
+#line 1889 "c-parse.y"
{ push_parm_decl (yyvsp[0].ttype); ;
break;}
case 353:
-#line 1886 "c-parse.y"
+#line 1891 "c-parse.y"
{ push_parm_decl (yyvsp[0].ttype); ;
break;}
case 354:
-#line 1893 "c-parse.y"
+#line 1898 "c-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ;
break;}
case 355:
-#line 1895 "c-parse.y"
+#line 1900 "c-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ;
break;}
case 356:
-#line 1897 "c-parse.y"
+#line 1902 "c-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 357:
-#line 1899 "c-parse.y"
+#line 1904 "c-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ;
break;}
case 358:
-#line 1901 "c-parse.y"
+#line 1906 "c-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 359:
-#line 1908 "c-parse.y"
+#line 1913 "c-parse.y"
{ pushlevel (0);
clear_parm_order ();
declare_parm_level (1); ;
break;}
case 360:
-#line 1912 "c-parse.y"
+#line 1917 "c-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
parmlist_tags_warning ();
poplevel (0, 0, 0); ;
break;}
case 362:
-#line 1920 "c-parse.y"
+#line 1925 "c-parse.y"
{ tree t;
for (t = yyvsp[-1].ttype; t; t = TREE_CHAIN (t))
if (TREE_VALUE (t) == NULL_TREE)
@@ -3313,19 +3318,19 @@ case 362:
yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, yyvsp[-1].ttype); ;
break;}
case 363:
-#line 1930 "c-parse.y"
+#line 1935 "c-parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
case 364:
-#line 1932 "c-parse.y"
+#line 1937 "c-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
case 365:
-#line 1938 "c-parse.y"
+#line 1943 "c-parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
case 366:
-#line 1940 "c-parse.y"
+#line 1945 "c-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
}
@@ -3526,5 +3531,5 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 1943 "c-parse.y"
+#line 1948 "c-parse.y"
diff --git a/gnu/usr.bin/cc/cc1/c-typeck.c b/gnu/usr.bin/cc/cc1/c-typeck.c
index d5283c6982b9..c40d08ab0026 100644
--- a/gnu/usr.bin/cc/cc1/c-typeck.c
+++ b/gnu/usr.bin/cc/cc1/c-typeck.c
@@ -655,7 +655,8 @@ type_lists_compatible_p (args1, args2)
/* Allow wait (union {union wait *u; int *i} *)
and wait (union wait *) to be compatible. */
if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
- && TYPE_NAME (TREE_VALUE (args1)) == 0
+ && (TYPE_NAME (TREE_VALUE (args1)) == 0
+ || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1)))
&& TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
&& tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
TYPE_SIZE (TREE_VALUE (args2))))
@@ -669,7 +670,8 @@ type_lists_compatible_p (args1, args2)
return 0;
}
else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
- && TYPE_NAME (TREE_VALUE (args2)) == 0
+ && (TYPE_NAME (TREE_VALUE (args2)) == 0
+ || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2)))
&& TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
&& tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
TYPE_SIZE (TREE_VALUE (args1))))
@@ -990,8 +992,11 @@ default_conversion (exp)
/* Constants can be used directly unless they're not loadable. */
if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp);
- /* Replace a nonvolatile const static variable with its value. */
- else if (optimize && TREE_CODE (exp) == VAR_DECL)
+
+ /* Replace a nonvolatile const static variable with its value unless
+ it is an array, in which case we must be sure that taking the
+ address of the array produces consistent results. */
+ else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)
{
exp = decl_constant_value (exp);
type = TREE_TYPE (exp);
@@ -1630,37 +1635,28 @@ convert_arguments (typelist, values, name, fundecl)
}
else
{
-#if 0 /* This turns out not to win--there's no way to write a prototype
- for a function whose arg type is a union with no tag. */
- /* Nameless union automatically casts the types it contains. */
- if (TREE_CODE (type) == UNION_TYPE && TYPE_NAME (type) == 0)
- {
- tree field;
-
- for (field = TYPE_FIELDS (type); field;
- field = TREE_CHAIN (field))
- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
- TYPE_MAIN_VARIANT (TREE_TYPE (val))))
- break;
-
- if (field)
- val = build1 (CONVERT_EXPR, type, val);
- }
-#endif
-
/* Optionally warn about conversions that
differ from the default conversions. */
if (warn_conversion)
{
int formal_prec = TYPE_PRECISION (type);
- if (TREE_CODE (type) != REAL_TYPE
+ if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
+ else if (TREE_CODE (type) == COMPLEX_TYPE
+ && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
+ warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
else if (TREE_CODE (type) == REAL_TYPE
- && TREE_CODE (TREE_TYPE (val)) != REAL_TYPE)
+ && INTEGRAL_TYPE_P (TREE_TYPE (val)))
warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
else if (TREE_CODE (type) == REAL_TYPE
+ && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
+ warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
+ /* ??? At some point, messages should be written about
+ conversions between complex types, but that's too messy
+ to do now. */
+ else if (TREE_CODE (type) == REAL_TYPE
&& TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
{
/* Warn if any argument is passed as `float',
@@ -1669,10 +1665,8 @@ convert_arguments (typelist, values, name, fundecl)
warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1);
}
/* Detect integer changing in width or signedness. */
- else if ((TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && (TREE_CODE (TREE_TYPE (val)) == INTEGER_TYPE
- || TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE))
+ else if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (val)))
{
tree would_have_been = default_conversion (val);
tree type1 = TREE_TYPE (would_have_been);
@@ -2798,7 +2792,7 @@ build_unary_op (code, xarg, noconvert)
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
? "increment" : "decrement"));
- inc = c_sizeof_nowarn (TREE_TYPE (result_type));
+ inc = c_size_in_bytes (TREE_TYPE (result_type));
}
else
inc = integer_one_node;
@@ -3211,6 +3205,18 @@ mark_addressable (exp)
IDENTIFIER_POINTER (DECL_NAME (x)));
return 0;
}
+
+ /* If we are making this addressable due to its having
+ volatile components, give a different error message. Also
+ handle the case of an unnamed parameter by not trying
+ to give the name. */
+
+ else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
+ {
+ error ("cannot put object with volatile field into register");
+ return 0;
+ }
+
pedwarn ("address of register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
}
@@ -3868,14 +3874,15 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* Arithmetic types all interconvert, and enum is treated like int. */
if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
|| codel == COMPLEX_TYPE)
- &&
- (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
- || coder == COMPLEX_TYPE))
+ && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
+ || coder == COMPLEX_TYPE))
return convert_and_check (type, rhs);
+
/* Conversion to a union from its member types. */
else if (codel == UNION_TYPE)
{
tree memb_types;
+
for (memb_types = TYPE_FIELDS (type); memb_types;
memb_types = TREE_CHAIN (memb_types))
{
@@ -3886,6 +3893,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
pedwarn ("ANSI C prohibits argument conversion to union type");
return build1 (NOP_EXPR, type, rhs);
}
+
else if (coder == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (memb_types)) == POINTER_TYPE)
{
@@ -3895,44 +3903,59 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* Any non-function converts to a [const][volatile] void *
and vice versa; otherwise, targets must be the same.
- Meanwhile, the lhs target must have all the qualifiers of the rhs. */
+ Meanwhile, the lhs target must have all the qualifiers of
+ the rhs. */
if (TYPE_MAIN_VARIANT (ttl) == void_type_node
|| TYPE_MAIN_VARIANT (ttr) == void_type_node
|| comp_target_types (memb_type, rhstype))
{
- /* Const and volatile mean something different for function types,
- so the usual warnings are not appropriate. */
+ /* Const and volatile mean something different for function
+ types, so the usual warnings are not appropriate. */
if (TREE_CODE (ttr) != FUNCTION_TYPE
|| TREE_CODE (ttl) != FUNCTION_TYPE)
{
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
warn_for_assignment ("%s discards `const' from pointer target type",
- get_spelling (errtype), funname, parmnum);
+ get_spelling (errtype), funname,
+ parmnum);
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
warn_for_assignment ("%s discards `volatile' from pointer target type",
- get_spelling (errtype), funname, parmnum);
+ get_spelling (errtype), funname,
+ parmnum);
}
else
{
- /* Because const and volatile on functions are restrictions
- that say the function will not do certain things,
- it is okay to use a const or volatile function
- where an ordinary one is wanted, but not vice-versa. */
+ /* Because const and volatile on functions are
+ restrictions that say the function will not do
+ certain things, it is okay to use a const or volatile
+ function where an ordinary one is wanted, but not
+ vice-versa. */
if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
warn_for_assignment ("%s makes `const *' function pointer from non-const",
- get_spelling (errtype), funname, parmnum);
+ get_spelling (errtype), funname,
+ parmnum);
if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
- get_spelling (errtype), funname, parmnum);
+ get_spelling (errtype), funname,
+ parmnum);
}
+
if (pedantic
&& !(fundecl != 0 && DECL_IN_SYSTEM_HEADER (fundecl)))
pedwarn ("ANSI C prohibits argument conversion to union type");
return build1 (NOP_EXPR, type, rhs);
}
}
+
+ /* Can convert integer zero to any pointer type. */
+ else if (TREE_CODE (TREE_TYPE (memb_types)) == POINTER_TYPE
+ && (integer_zerop (rhs)
+ || (TREE_CODE (rhs) == NOP_EXPR
+ && integer_zerop (TREE_OPERAND (rhs, 0)))))
+ return build1 (NOP_EXPR, type, null_pointer_node);
}
}
+
/* Conversions among pointers */
else if (codel == POINTER_TYPE && coder == POINTER_TYPE)
{
@@ -5155,8 +5178,8 @@ push_init_level (implicit)
/* Structure elements may require alignment. Do this now
if necessary for the subaggregate. */
- if (constructor_incremental && TREE_CODE (constructor_type) == RECORD_TYPE
- && constructor_fields)
+ if (constructor_incremental && constructor_type != 0
+ && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields)
{
/* Advance to offset of this element. */
if (! tree_int_cst_equal (constructor_bit_index,
@@ -6020,6 +6043,7 @@ process_init_element (value)
/* Otherwise, if we have come to a subaggregate,
and we don't have an element of its type, push into it. */
else if (value != 0 && !constructor_no_implicit
+ && value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|| fieldcode == UNION_TYPE))
@@ -6083,6 +6107,7 @@ process_init_element (value)
/* Otherwise, if we have come to a subaggregate,
and we don't have an element of its type, push into it. */
else if (value != 0 && !constructor_no_implicit
+ && value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|| fieldcode == UNION_TYPE))
@@ -6126,6 +6151,7 @@ process_init_element (value)
/* Otherwise, if we have come to a subaggregate,
and we don't have an element of its type, push into it. */
else if (value != 0 && !constructor_no_implicit
+ && value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
|| eltcode == UNION_TYPE))
@@ -6142,6 +6168,10 @@ process_init_element (value)
break;
}
+ /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once. */
+ if (constructor_range_end)
+ value = save_expr (value);
+
/* Now output the actual element.
Ordinarily, output once.
If there is a range, repeat it till we advance past the range. */