Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / gcc / c / c-fold.c
1 /* Support for fully folding sub-trees of an expression for C compiler.
2    Copyright (C) 1992-2018 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "function.h"
25 #include "bitmap.h"
26 #include "c-tree.h"
27 #include "intl.h"
28 #include "gimplify.h"
29
30 static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool,
31                                    bool);
32
33 /* If DISABLE is true, stop issuing warnings.  This is used when
34    parsing code that we know will not be executed.  This function may
35    be called multiple times, and works as a stack.  */
36
37 static void
38 c_disable_warnings (bool disable)
39 {
40   if (disable)
41     {
42       ++c_inhibit_evaluation_warnings;
43       fold_defer_overflow_warnings ();
44     }
45 }
46
47 /* If ENABLE is true, reenable issuing warnings.  */
48
49 static void
50 c_enable_warnings (bool enable)
51 {
52   if (enable)
53     {
54       --c_inhibit_evaluation_warnings;
55       fold_undefer_and_ignore_overflow_warnings ();
56     }
57 }
58
59 /* Try to fold ARRAY_REF ary[index] if possible and not handled by
60    normal fold, return NULL_TREE otherwise.  */
61
62 static tree
63 c_fold_array_ref (tree type, tree ary, tree index)
64 {
65   if (TREE_CODE (ary) != STRING_CST
66       || TREE_CODE (index) != INTEGER_CST
67       || TREE_OVERFLOW (index)
68       || TREE_CODE (TREE_TYPE (ary)) != ARRAY_TYPE
69       || !tree_fits_uhwi_p (index))
70     return NULL_TREE;
71
72   tree elem_type = TREE_TYPE (TREE_TYPE (ary));
73   unsigned elem_nchars = (TYPE_PRECISION (elem_type)
74                           / TYPE_PRECISION (char_type_node));
75   unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
76   tree nelts = array_type_nelts (TREE_TYPE (ary));
77   bool dummy1 = true, dummy2 = true;
78   nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
79   unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
80   if (!tree_int_cst_le (index, nelts)
81       || i >= len
82       || i + elem_nchars > len)
83     return NULL_TREE;
84
85   if (elem_nchars == 1)
86     return build_int_cst (type, TREE_STRING_POINTER (ary)[i]);
87
88   const unsigned char *ptr
89     = ((const unsigned char *)TREE_STRING_POINTER (ary) + i * elem_nchars);
90   return native_interpret_expr (type, ptr, elem_nchars);
91 }
92
93 /* Fully fold EXPR, an expression that was not folded (beyond integer
94    constant expressions and null pointer constants) when being built
95    up.  If IN_INIT, this is in a static initializer and certain
96    changes are made to the folding done.  Clear *MAYBE_CONST if
97    MAYBE_CONST is not NULL and EXPR is definitely not a constant
98    expression because it contains an evaluated operator (in C99) or an
99    operator outside of sizeof returning an integer constant (in C90)
100    not permitted in constant expressions, or because it contains an
101    evaluated arithmetic overflow.  (*MAYBE_CONST should typically be
102    set to true by callers before calling this function.)  Return the
103    folded expression.  Function arguments have already been folded
104    before calling this function, as have the contents of SAVE_EXPR,
105    TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and
106    C_MAYBE_CONST_EXPR.  LVAL is true if it should be treated as an
107    lvalue.  */
108
109 tree
110 c_fully_fold (tree expr, bool in_init, bool *maybe_const, bool lval)
111 {
112   tree ret;
113   tree eptype = NULL_TREE;
114   bool dummy = true;
115   bool maybe_const_itself = true;
116   location_t loc = EXPR_LOCATION (expr);
117
118   if (!maybe_const)
119     maybe_const = &dummy;
120   if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
121     {
122       eptype = TREE_TYPE (expr);
123       expr = TREE_OPERAND (expr, 0);
124     }
125   ret = c_fully_fold_internal (expr, in_init, maybe_const,
126                                &maybe_const_itself, false, lval);
127   if (eptype)
128     ret = fold_convert_loc (loc, eptype, ret);
129   *maybe_const &= maybe_const_itself;
130   return ret;
131 }
132
133 /* Internal helper for c_fully_fold.  EXPR and IN_INIT are as for
134    c_fully_fold.  *MAYBE_CONST_OPERANDS is cleared because of operands
135    not permitted, while *MAYBE_CONST_ITSELF is cleared because of
136    arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from
137    both evaluated and unevaluated subexpressions while
138    *MAYBE_CONST_ITSELF is carried from only evaluated
139    subexpressions).  FOR_INT_CONST indicates if EXPR is an expression
140    with integer constant operands, and if any of the operands doesn't
141    get folded to an integer constant, don't fold the expression itself.
142    LVAL indicates folding of lvalue, where we can't replace it with
143    an rvalue.  */
144
145 static tree
146 c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
147                        bool *maybe_const_itself, bool for_int_const, bool lval)
148 {
149   tree ret = expr;
150   enum tree_code code = TREE_CODE (expr);
151   enum tree_code_class kind = TREE_CODE_CLASS (code);
152   location_t loc = EXPR_LOCATION (expr);
153   tree op0, op1, op2, op3;
154   tree orig_op0, orig_op1, orig_op2;
155   bool op0_const = true, op1_const = true, op2_const = true;
156   bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
157   bool nowarning = TREE_NO_WARNING (expr);
158   bool unused_p;
159   bool op0_lval = false;
160   source_range old_range;
161
162   /* Constants, declarations, statements, errors, and anything else not
163      counted as an expression cannot usefully be folded further at this
164      point.  */
165   if (!IS_EXPR_CODE_CLASS (kind) || kind == tcc_statement)
166     {
167       /* Except for variables which we can optimize to its initializer.  */
168       if (VAR_P (expr) && !lval && (optimize || in_init))
169         {
170           if (in_init)
171             ret = decl_constant_value_1 (expr, true);
172           else
173             {
174               ret = decl_constant_value (expr);
175               if (ret != expr
176                   && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode
177                       || TREE_CODE (TREE_TYPE (ret)) == ARRAY_TYPE))
178                 return expr;
179             }
180           /* Avoid unwanted tree sharing between the initializer and current
181              function's body where the tree can be modified e.g. by the
182              gimplifier.  */
183           if (ret != expr && TREE_STATIC (expr))
184             ret = unshare_expr (ret);
185           return ret;
186         }
187       return expr;
188     }
189
190   if (IS_EXPR_CODE_CLASS (kind))
191     old_range = EXPR_LOCATION_RANGE (expr);
192
193   /* Operands of variable-length expressions (function calls) have
194      already been folded, as have __builtin_* function calls, and such
195      expressions cannot occur in constant expressions.  */
196   if (kind == tcc_vl_exp)
197     {
198       *maybe_const_operands = false;
199       ret = fold (expr);
200       goto out;
201     }
202
203   if (code == C_MAYBE_CONST_EXPR)
204     {
205       tree pre = C_MAYBE_CONST_EXPR_PRE (expr);
206       tree inner = C_MAYBE_CONST_EXPR_EXPR (expr);
207       if (C_MAYBE_CONST_EXPR_NON_CONST (expr))
208         *maybe_const_operands = false;
209       if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr))
210         {
211           *maybe_const_itself = false;
212           inner = c_fully_fold_internal (inner, in_init, maybe_const_operands,
213                                          maybe_const_itself, true, lval);
214         }
215       if (pre && !in_init)
216         ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner);
217       else
218         ret = inner;
219       goto out;
220     }
221
222   /* Assignment, increment, decrement, function call and comma
223      operators, and statement expressions, cannot occur in constant
224      expressions if evaluated / outside of sizeof.  (Function calls
225      were handled above, though VA_ARG_EXPR is treated like a function
226      call here, and statement expressions are handled through
227      C_MAYBE_CONST_EXPR to avoid folding inside them.)  */
228   switch (code)
229     {
230     case MODIFY_EXPR:
231     case PREDECREMENT_EXPR:
232     case PREINCREMENT_EXPR:
233     case POSTDECREMENT_EXPR:
234     case POSTINCREMENT_EXPR:
235     case COMPOUND_EXPR:
236       *maybe_const_operands = false;
237       break;
238
239     case VA_ARG_EXPR:
240     case TARGET_EXPR:
241     case BIND_EXPR:
242     case OBJ_TYPE_REF:
243       *maybe_const_operands = false;
244       ret = fold (expr);
245       goto out;
246
247     default:
248       break;
249     }
250
251   /* Fold individual tree codes as appropriate.  */
252   switch (code)
253     {
254     case COMPOUND_LITERAL_EXPR:
255       /* Any non-constancy will have been marked in a containing
256          C_MAYBE_CONST_EXPR; there is no more folding to do here.  */
257       goto out;
258
259     case COMPONENT_REF:
260       orig_op0 = op0 = TREE_OPERAND (expr, 0);
261       op1 = TREE_OPERAND (expr, 1);
262       op2 = TREE_OPERAND (expr, 2);
263       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
264                                    maybe_const_itself, for_int_const, lval);
265       STRIP_TYPE_NOPS (op0);
266       if (op0 != orig_op0)
267         ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
268       if (ret != expr)
269         {
270           TREE_READONLY (ret) = TREE_READONLY (expr);
271           TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
272         }
273       if (!lval)
274         ret = fold (ret);
275       goto out;
276
277     case ARRAY_REF:
278       orig_op0 = op0 = TREE_OPERAND (expr, 0);
279       orig_op1 = op1 = TREE_OPERAND (expr, 1);
280       op2 = TREE_OPERAND (expr, 2);
281       op3 = TREE_OPERAND (expr, 3);
282       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
283                                    maybe_const_itself, for_int_const, lval);
284       STRIP_TYPE_NOPS (op0);
285       op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
286                                    maybe_const_itself, for_int_const, false);
287       STRIP_TYPE_NOPS (op1);
288       /* Fold "foo"[2] in initializers.  */
289       if (!lval && in_init)
290         {
291           ret = c_fold_array_ref (TREE_TYPE (expr), op0, op1);
292           if (ret)
293             goto out;
294           ret = expr;
295         }
296       if (op0 != orig_op0 || op1 != orig_op1)
297         ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
298       if (ret != expr)
299         {
300           TREE_READONLY (ret) = TREE_READONLY (expr);
301           TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
302           TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
303         }
304       if (!lval)
305         ret = fold (ret);
306       goto out;
307
308     case MODIFY_EXPR:
309     case PREDECREMENT_EXPR:
310     case PREINCREMENT_EXPR:
311     case POSTDECREMENT_EXPR:
312     case POSTINCREMENT_EXPR:
313       op0_lval = true;
314       /* FALLTHRU */
315     case COMPOUND_EXPR:
316     case PLUS_EXPR:
317     case MINUS_EXPR:
318     case MULT_EXPR:
319     case POINTER_PLUS_EXPR:
320     case POINTER_DIFF_EXPR:
321     case TRUNC_DIV_EXPR:
322     case CEIL_DIV_EXPR:
323     case FLOOR_DIV_EXPR:
324     case TRUNC_MOD_EXPR:
325     case RDIV_EXPR:
326     case EXACT_DIV_EXPR:
327     case LSHIFT_EXPR:
328     case RSHIFT_EXPR:
329     case BIT_IOR_EXPR:
330     case BIT_XOR_EXPR:
331     case BIT_AND_EXPR:
332     case LT_EXPR:
333     case LE_EXPR:
334     case GT_EXPR:
335     case GE_EXPR:
336     case EQ_EXPR:
337     case NE_EXPR:
338     case COMPLEX_EXPR:
339     case TRUTH_AND_EXPR:
340     case TRUTH_OR_EXPR:
341     case TRUTH_XOR_EXPR:
342     case UNORDERED_EXPR:
343     case ORDERED_EXPR:
344     case UNLT_EXPR:
345     case UNLE_EXPR:
346     case UNGT_EXPR:
347     case UNGE_EXPR:
348     case UNEQ_EXPR:
349       /* Binary operations evaluating both arguments (increment and
350          decrement are binary internally in GCC).  */
351       orig_op0 = op0 = TREE_OPERAND (expr, 0);
352       orig_op1 = op1 = TREE_OPERAND (expr, 1);
353       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
354                                    maybe_const_itself, for_int_const,
355                                    op0_lval);
356       STRIP_TYPE_NOPS (op0);
357       /* The RHS of a MODIFY_EXPR was fully folded when building that
358          expression for the sake of conversion warnings.  */
359       if (code != MODIFY_EXPR)
360         op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
361                                      maybe_const_itself, for_int_const, false);
362       STRIP_TYPE_NOPS (op1);
363
364       if (for_int_const && (TREE_CODE (op0) != INTEGER_CST
365                             || TREE_CODE (op1) != INTEGER_CST))
366         goto out;
367
368       if (op0 != orig_op0 || op1 != orig_op1 || in_init)
369         ret = in_init
370           ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
371           : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
372       else
373         ret = fold (expr);
374       if (TREE_OVERFLOW_P (ret)
375           && !TREE_OVERFLOW_P (op0)
376           && !TREE_OVERFLOW_P (op1))
377         overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr);
378       if (code == LSHIFT_EXPR
379           && TREE_CODE (orig_op0) != INTEGER_CST
380           && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
381           && TREE_CODE (op0) == INTEGER_CST
382           && c_inhibit_evaluation_warnings == 0
383           && tree_int_cst_sgn (op0) < 0)
384         warning_at (loc, OPT_Wshift_negative_value,
385                     "left shift of negative value");
386       if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR)
387           && TREE_CODE (orig_op1) != INTEGER_CST
388           && TREE_CODE (op1) == INTEGER_CST
389           && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
390           && c_inhibit_evaluation_warnings == 0)
391         {
392           if (tree_int_cst_sgn (op1) < 0)
393             warning_at (loc, OPT_Wshift_count_negative,
394                         (code == LSHIFT_EXPR
395                          ? G_("left shift count is negative")
396                          : G_("right shift count is negative")));
397           else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
398                     || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
399                    && compare_tree_int (op1,
400                                         TYPE_PRECISION (TREE_TYPE (orig_op0)))
401                       >= 0)
402             warning_at (loc, OPT_Wshift_count_overflow,
403                         (code == LSHIFT_EXPR
404                          ? G_("left shift count >= width of type")
405                          : G_("right shift count >= width of type")));
406           else if (TREE_CODE (TREE_TYPE (orig_op0)) == VECTOR_TYPE
407                    && compare_tree_int (op1,
408                                         TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig_op0))))
409                       >= 0)
410             warning_at (loc, OPT_Wshift_count_overflow,
411                         code == LSHIFT_EXPR
412                         ? G_("left shift count >= width of vector element")
413                         : G_("right shift count >= width of vector element"));
414         }
415       if (code == LSHIFT_EXPR
416           /* If either OP0 has been folded to INTEGER_CST...  */
417           && ((TREE_CODE (orig_op0) != INTEGER_CST
418                && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
419                && TREE_CODE (op0) == INTEGER_CST)
420               /* ...or if OP1 has been folded to INTEGER_CST...  */
421               || (TREE_CODE (orig_op1) != INTEGER_CST
422                   && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
423                   && TREE_CODE (op1) == INTEGER_CST))
424           && c_inhibit_evaluation_warnings == 0)
425         /* ...then maybe we can detect an overflow.  */
426         maybe_warn_shift_overflow (loc, op0, op1);
427       if ((code == TRUNC_DIV_EXPR
428            || code == CEIL_DIV_EXPR
429            || code == FLOOR_DIV_EXPR
430            || code == EXACT_DIV_EXPR
431            || code == TRUNC_MOD_EXPR)
432           && TREE_CODE (orig_op1) != INTEGER_CST
433           && TREE_CODE (op1) == INTEGER_CST
434           && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
435               || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
436           && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE)
437         warn_for_div_by_zero (loc, op1);
438       goto out;
439
440     case ADDR_EXPR:
441       op0_lval = true;
442       goto unary;
443     case REALPART_EXPR:
444     case IMAGPART_EXPR:
445     case VIEW_CONVERT_EXPR:
446       op0_lval = lval;
447       /* FALLTHRU */
448     case INDIRECT_REF:
449     case FIX_TRUNC_EXPR:
450     case FLOAT_EXPR:
451     CASE_CONVERT:
452     case ADDR_SPACE_CONVERT_EXPR:
453     case NON_LVALUE_EXPR:
454     case NEGATE_EXPR:
455     case BIT_NOT_EXPR:
456     case TRUTH_NOT_EXPR:
457     case CONJ_EXPR:
458     unary:
459       /* Unary operations.  */
460       orig_op0 = op0 = TREE_OPERAND (expr, 0);
461       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
462                                    maybe_const_itself, for_int_const,
463                                    op0_lval);
464       STRIP_TYPE_NOPS (op0);
465
466       if (for_int_const && TREE_CODE (op0) != INTEGER_CST)
467         goto out;
468
469       /* ??? Cope with user tricks that amount to offsetof.  The middle-end is
470          not prepared to deal with them if they occur in initializers.  */
471       if (op0 != orig_op0
472           && code == ADDR_EXPR
473           && (op1 = get_base_address (op0)) != NULL_TREE
474           && INDIRECT_REF_P (op1)
475           && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
476         ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0));
477       else if (op0 != orig_op0 || in_init)
478         ret = in_init
479           ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
480           : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
481       else
482         ret = fold (expr);
483       if (code == INDIRECT_REF
484           && ret != expr
485           && INDIRECT_REF_P (ret))
486         {
487           TREE_READONLY (ret) = TREE_READONLY (expr);
488           TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
489           TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
490         }
491       switch (code)
492         {
493         case FIX_TRUNC_EXPR:
494         case FLOAT_EXPR:
495         CASE_CONVERT:
496           /* Don't warn about explicit conversions.  We will already
497              have warned about suspect implicit conversions.  */
498           break;
499
500         default:
501           if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0))
502             overflow_warning (EXPR_LOCATION (expr), ret, op0);
503           break;
504         }
505       goto out;
506
507     case TRUTH_ANDIF_EXPR:
508     case TRUTH_ORIF_EXPR:
509       /* Binary operations not necessarily evaluating both
510          arguments.  */
511       orig_op0 = op0 = TREE_OPERAND (expr, 0);
512       orig_op1 = op1 = TREE_OPERAND (expr, 1);
513       op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
514                                    for_int_const, false);
515       STRIP_TYPE_NOPS (op0);
516
517       unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
518                           ? truthvalue_false_node
519                           : truthvalue_true_node));
520       c_disable_warnings (unused_p);
521       op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
522                                    for_int_const, false);
523       STRIP_TYPE_NOPS (op1);
524       c_enable_warnings (unused_p);
525
526       if (for_int_const
527           && (TREE_CODE (op0) != INTEGER_CST
528               /* Require OP1 be an INTEGER_CST only if it's evaluated.  */
529               || (!unused_p && TREE_CODE (op1) != INTEGER_CST)))
530         goto out;
531
532       if (op0 != orig_op0 || op1 != orig_op1 || in_init)
533         ret = in_init
534           ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
535           : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
536       else
537         ret = fold (expr);
538       *maybe_const_operands &= op0_const;
539       *maybe_const_itself &= op0_const_self;
540       if (!(flag_isoc99
541             && op0_const
542             && op0_const_self
543             && (code == TRUTH_ANDIF_EXPR
544                 ? op0 == truthvalue_false_node
545                 : op0 == truthvalue_true_node)))
546         *maybe_const_operands &= op1_const;
547       if (!(op0_const
548             && op0_const_self
549             && (code == TRUTH_ANDIF_EXPR
550                 ? op0 == truthvalue_false_node
551                 : op0 == truthvalue_true_node)))
552         *maybe_const_itself &= op1_const_self;
553       goto out;
554
555     case COND_EXPR:
556       orig_op0 = op0 = TREE_OPERAND (expr, 0);
557       orig_op1 = op1 = TREE_OPERAND (expr, 1);
558       orig_op2 = op2 = TREE_OPERAND (expr, 2);
559       op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
560                                    for_int_const, false);
561
562       STRIP_TYPE_NOPS (op0);
563       c_disable_warnings (op0 == truthvalue_false_node);
564       op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
565                                    for_int_const, false);
566       STRIP_TYPE_NOPS (op1);
567       c_enable_warnings (op0 == truthvalue_false_node);
568
569       c_disable_warnings (op0 == truthvalue_true_node);
570       op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self,
571                                    for_int_const, false);
572       STRIP_TYPE_NOPS (op2);
573       c_enable_warnings (op0 == truthvalue_true_node);
574
575       if (for_int_const
576           && (TREE_CODE (op0) != INTEGER_CST
577               /* Only the evaluated operand must be an INTEGER_CST.  */
578               || (op0 == truthvalue_true_node
579                   ? TREE_CODE (op1) != INTEGER_CST
580                   : TREE_CODE (op2) != INTEGER_CST)))
581         goto out;
582
583       if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
584         ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
585       else
586         ret = fold (expr);
587       *maybe_const_operands &= op0_const;
588       *maybe_const_itself &= op0_const_self;
589       if (!(flag_isoc99
590             && op0_const
591             && op0_const_self
592             && op0 == truthvalue_false_node))
593         *maybe_const_operands &= op1_const;
594       if (!(op0_const
595             && op0_const_self
596             && op0 == truthvalue_false_node))
597         *maybe_const_itself &= op1_const_self;
598       if (!(flag_isoc99
599             && op0_const
600             && op0_const_self
601             && op0 == truthvalue_true_node))
602         *maybe_const_operands &= op2_const;
603       if (!(op0_const
604             && op0_const_self
605             && op0 == truthvalue_true_node))
606         *maybe_const_itself &= op2_const_self;
607       goto out;
608
609     case VEC_COND_EXPR:
610       orig_op0 = op0 = TREE_OPERAND (expr, 0);
611       orig_op1 = op1 = TREE_OPERAND (expr, 1);
612       orig_op2 = op2 = TREE_OPERAND (expr, 2);
613       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
614                                    maybe_const_itself, for_int_const, false);
615       STRIP_TYPE_NOPS (op0);
616       op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
617                                    maybe_const_itself, for_int_const, false);
618       STRIP_TYPE_NOPS (op1);
619       op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands,
620                                    maybe_const_itself, for_int_const, false);
621       STRIP_TYPE_NOPS (op2);
622
623       if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
624         ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
625       else
626         ret = fold (expr);
627       goto out;
628
629     case EXCESS_PRECISION_EXPR:
630       /* Each case where an operand with excess precision may be
631          encountered must remove the EXCESS_PRECISION_EXPR around
632          inner operands and possibly put one around the whole
633          expression or possibly convert to the semantic type (which
634          c_fully_fold does); we cannot tell at this stage which is
635          appropriate in any particular case.  */
636       gcc_unreachable ();
637
638     case SAVE_EXPR:
639       /* Make sure to fold the contents of a SAVE_EXPR exactly once.  */
640       op0 = TREE_OPERAND (expr, 0);
641       if (!SAVE_EXPR_FOLDED_P (expr))
642         {
643           op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
644                                        maybe_const_itself, for_int_const,
645                                        false);
646           TREE_OPERAND (expr, 0) = op0;
647           SAVE_EXPR_FOLDED_P (expr) = true;
648         }
649       /* Return the SAVE_EXPR operand if it is invariant.  */
650       if (tree_invariant_p (op0))
651         ret = op0;
652       goto out;
653
654     default:
655       /* Various codes may appear through folding built-in functions
656          and their arguments.  */
657       goto out;
658     }
659
660  out:
661   /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks
662      have been done by this point, so remove them again.  */
663   nowarning |= TREE_NO_WARNING (ret);
664   STRIP_TYPE_NOPS (ret);
665   if (nowarning && !TREE_NO_WARNING (ret))
666     {
667       if (!CAN_HAVE_LOCATION_P (ret))
668         ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
669       TREE_NO_WARNING (ret) = 1;
670     }
671   if (ret != expr)
672     {
673       protected_set_expr_location (ret, loc);
674       if (IS_EXPR_CODE_CLASS (kind))
675         set_source_range (ret, old_range.m_start, old_range.m_finish);
676     }
677   return ret;
678 }
679
680 /* Fold X for consideration by one of the warning functions when checking
681    whether an expression has a constant value.  */
682
683 tree
684 fold_for_warn (tree x)
685 {
686   /* The C front-end has already folded X appropriately.  */
687   return x;
688 }