]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/staticcond.c
ipa-param-manip: Be careful about a reallocating hash_map
[thirdparty/gcc.git] / gcc / d / dmd / staticcond.c
1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/staticcond.c
9 */
10
11 #include "mars.h"
12 #include "expression.h"
13 #include "mtype.h"
14 #include "scope.h"
15
16 /********************************************
17 * Semantically analyze and then evaluate a static condition at compile time.
18 * This is special because short circuit operators &&, || and ?: at the top
19 * level are not semantically analyzed if the result of the expression is not
20 * necessary.
21 * Params:
22 * exp = original expression, for error messages
23 * Returns:
24 * true if evaluates to true
25 */
26
27 bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors)
28 {
29 if (e->op == TOKandand || e->op == TOKoror)
30 {
31 LogicalExp *aae = (LogicalExp *)e;
32 bool result = evalStaticCondition(sc, exp, aae->e1, errors);
33 if (errors)
34 return false;
35 if (e->op == TOKandand)
36 {
37 if (!result)
38 return false;
39 }
40 else
41 {
42 if (result)
43 return true;
44 }
45 result = evalStaticCondition(sc, exp, aae->e2, errors);
46 return !errors && result;
47 }
48
49 if (e->op == TOKquestion)
50 {
51 CondExp *ce = (CondExp *)e;
52 bool result = evalStaticCondition(sc, exp, ce->econd, errors);
53 if (errors)
54 return false;
55 Expression *leg = result ? ce->e1 : ce->e2;
56 result = evalStaticCondition(sc, exp, leg, errors);
57 return !errors && result;
58 }
59
60 unsigned nerrors = global.errors;
61
62 sc = sc->startCTFE();
63 sc->flags |= SCOPEcondition;
64
65 e = expressionSemantic(e, sc);
66 e = resolveProperties(sc, e);
67
68 sc = sc->endCTFE();
69 e = e->optimize(WANTvalue);
70
71 if (nerrors != global.errors ||
72 e->op == TOKerror ||
73 e->type->toBasetype() == Type::terror)
74 {
75 errors = true;
76 return false;
77 }
78
79 if (!e->type->isBoolean())
80 {
81 exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars());
82 errors = true;
83 return false;
84 }
85
86 e = e->ctfeInterpret();
87
88 if (e->isBool(true))
89 return true;
90 else if (e->isBool(false))
91 return false;
92
93 e->error("expression %s is not constant", e->toChars());
94 errors = true;
95 return false;
96 }