summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cc/cc1
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1994-11-03 06:52:42 +0000
committerphk <phk@FreeBSD.org>1994-11-03 06:52:42 +0000
commitbbd23b334df6ee37516cf9398aff07483aeadb58 (patch)
tree50f1f9fa63ff73191f024d12c1c848e9cdcf55f8 /gnu/usr.bin/cc/cc1
parent2ef8552dd502af4e382f6c6346c4d35a0608e7b1 (diff)
downloadFreeBSD-src-bbd23b334df6ee37516cf9398aff07483aeadb58.zip
FreeBSD-src-bbd23b334df6ee37516cf9398aff07483aeadb58.tar.gz
----------------------------------
GCC-2.6.1 COMES TO FREEBSD-current ---------------------------------- Everybody needs to 'make world'. Oakland, Nov 2nd 1994. In a surprise move this sunny afternoon, the release- engineer for the slightly delayed FreeBSD-2.0, Poul-Henning Kamp (28), decided to pull in the new version 2.6.1 of the GNU C-compiler. The new version of the compiler was release today at noon, and hardly 9 hours later it was committed into the FreeBSD-current source-repository. "It's is simply because we have had too much trouble with the version 2.6.0 of the compiler" Poul-Henning told the FreeBSD-Gazette, "we took a gamble when we decided to use that as our compiler for the 2.0 release, but it seems to pay of in the end now" he concludes. The move has not been discussed on the "core" list at all, and will come as a surprise for most Poul-Hennings peers. "I have only discussed it with Jordan [J. K. Hubbard, the FreeBSD's resident humourist], and we agreed that we needed to do it, so ... I did it!". After a breath he added with a grin: "My email will probably get an all time 'disk-full' now!". This will bring quite a flag-day to the FreeBSD developers, the patch-file is almost 1.4 Megabyte, and they will have to run "make world" to get entirely -current again. "Too bad, but we just had to do this." Was the only comment from Poul-Henning to these problems. When asked how this move would impact the 2.0 release-date, Poul-Hennings face grew dark, he mumbled some very Danish words while he moved his fingers in strange geometrical patterns. Immediately something ecclipsed the Sun, a minor tremor shook the buildings, and the temperature fell significantly. We decided not to pursure the question. ----------- JOB-SECTION ----------- Are you a dedicated GCC-hacker ? We BADLY need somebody to look at the 'freebsd' OS in gcc, sanitize it and carry the patches back to the GNU people. In particular, we need to get out of the "i386-only" spot we are in now. I have the stuff to take a gnu-dist into bmake-form, and will do that part. Please apply to phk@freebsd.org No Novice Need Apply.
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 c1a8dc9..995009a 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 5120144..8a6465c 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 d5283c6..c40d08a 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. */
OpenPOWER on IntegriCloud