xref: /freebsd/contrib/bmake/unit-tests/cond-undef-lint.mk (revision a90b9d0159070121c221b966469c3e36d912bf82)
1# $NetBSD: cond-undef-lint.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $
2#
3# Tests for defined and undefined variables in .if conditions, in lint mode.
4#
5# As of 2020-09-14, lint mode contains experimental code for printing
6# accurate error messages in case of undefined variables, instead of the
7# wrong "Malformed condition".
8#
9# See also:
10#	opt-debug-lint.mk
11
12.MAKEFLAGS: -dL
13
14# DEF is defined, UNDEF is not.
15DEF=		defined
16
17# An expression based on a defined variable is fine.
18.if !${DEF}
19.  error
20.endif
21
22# Since the condition fails to evaluate, neither of the branches is taken.
23# expect+2: Malformed conditional (${UNDEF})
24# expect+1: Variable "UNDEF" is undefined
25.if ${UNDEF}
26.  error
27.else
28.  error
29.endif
30
31# The variable name depends on the undefined variable, which is probably a
32# mistake.  The variable UNDEF, as used here, can be easily turned into
33# an expression that is always defined, using the :U modifier.
34#
35# The outer expression does not generate an error message since there was
36# already an error evaluating this variable's name.
37#
38# TODO: Suppress the error message "Variable VAR. is undefined".  That part
39# of the expression must not be evaluated at all.
40# expect+3: Variable "UNDEF" is undefined
41# expect+2: Variable "VAR." is undefined
42# expect+1: Malformed conditional (${VAR.${UNDEF}})
43.if ${VAR.${UNDEF}}
44.  error
45.else
46.  error
47.endif
48
49# The variable VAR.defined is not defined and thus generates an error message.
50#
51# TODO: This pattern looks a lot like CFLAGS.${OPSYS}, which is at least
52# debatable.  Or would any practical use of CFLAGS.${OPSYS} be via an indirect
53# expression, as in the next example?
54# expect+2: Variable "VAR.defined" is undefined
55# expect+1: Malformed conditional (${VAR.${DEF}})
56.if ${VAR.${DEF}}
57.  error
58.else
59.  error
60.endif
61
62
63# Variables that are referenced indirectly may be undefined in a condition.
64#
65# A practical example for this is CFLAGS, which consists of CWARNS, COPTS
66# and a few others.  Just because these nested variables are not defined,
67# this does not make the condition invalid.
68#
69# The crucial point is that at the point where the variable appears in the
70# condition, there is no way to influence the definedness of the nested
71# variables.  In particular, there is no modifier that would turn undefined
72# nested variables into empty strings, as an equivalent to the :U modifier.
73INDIRECT=	${NESTED_UNDEF} ${NESTED_DEF}
74NESTED_DEF=	nested-defined
75
76# Since NESTED_UNDEF is not controllable at this point, it must not generate
77# an error message, and it doesn't do so, since 2020-09-14.
78.if !${INDIRECT}
79.  error
80.endif
81