1# $NetBSD: opt-debug-lint.mk,v 1.15 2023/06/01 20:56:35 rillig Exp $
2#
3# Tests for the -dL command line option, which runs additional checks
4# to catch common mistakes, such as unclosed variable expressions.
5
6.MAKEFLAGS: -dL
7
8# Since 2020-09-13, undefined variables that are used on the left-hand side
9# of a condition at parse time get a proper error message.  Before, the
10# error message was "Malformed conditional" only, which was wrong and
11# misleading.  The form of the condition is totally fine, it's the evaluation
12# that fails.
13#
14# Since 2020-09-13, the "Malformed conditional" error message is not printed
15# anymore.
16#
17# See also:
18#	cond-undef-lint.mk
19# expect+2: Malformed conditional ($X)
20# expect+1: Variable "X" is undefined
21.if $X
22.  error
23.endif
24
25# The dynamic variables like .TARGET are treated specially.  It does not make
26# sense to expand them in the global scope since they will never be defined
27# there under normal circumstances.  Therefore they expand to a string that
28# will later be expanded correctly, when the variable is evaluated again in
29# the scope of an actual target.
30#
31# Even though the "@" variable is not defined at this point, this is not an
32# error.  In all practical cases, this is no problem.  This particular test
33# case is made up and unrealistic.
34.if $@ != "\$(.TARGET)"
35.  error
36.endif
37
38# Since 2020-09-13, Var_Parse properly reports errors for undefined variables,
39# but only in lint mode.  Before, it had only silently returned var_Error,
40# hoping for the caller to print an error message.  This resulted in the
41# well-known "Malformed conditional" error message, even though the
42# conditional was well-formed and the only error was an undefined variable.
43# expect+2: Malformed conditional (${UNDEF})
44# expect+1: Variable "UNDEF" is undefined
45.if ${UNDEF}
46.  error
47.endif
48
49# Since 2020-09-14, dependency lines may contain undefined variables.
50# Before, undefined variables were forbidden, but this distinction was not
51# observable from the outside of the function Var_Parse.
52${UNDEF}: ${UNDEF}
53
54# In a condition that has a defined(UNDEF) guard, all guarded conditions
55# may assume that the variable is defined since they will only be evaluated
56# if the variable is indeed defined.  Otherwise they are only parsed, and
57# for parsing it doesn't make a difference whether the variable is defined
58# or not.
59.if defined(UNDEF) && exists(${UNDEF})
60.  error
61.endif
62
63# Since 2020-10-03, in lint mode the variable modifier must be separated
64# by colons.  See varparse-mod.mk.
65# expect+2: Missing delimiter ':' after modifier "L"
66# expect+1: Missing delimiter ':' after modifier "P"
67.if ${value:LPL} != "value"
68.  error
69.endif
70
71# Between 2020-10-03 and var.c 1.752 from 2020-12-20, in lint mode the
72# variable modifier had to be separated by colons.  This was wrong though
73# since make always fell back trying to parse the indirect modifier as a
74# SysV modifier.
75# expect+1: Unknown modifier "${"
76.if ${value:${:UL}PL} != "LPL}"		# FIXME: "LPL}" is unexpected here.
77.  error ${value:${:UL}PL}
78.endif
79
80# Typically, an indirect modifier is followed by a colon or the closing
81# brace.  This one isn't, therefore make falls back to parsing it as the SysV
82# modifier ":lue=lid".
83.if ${value:L:${:Ulue}=${:Ulid}} != "valid"
84.  error
85.endif
86
87# In lint mode, the whole variable text is evaluated to check for unclosed
88# expressions and unknown operators.  During this check, the subexpression
89# '${:U2}' is not expanded, instead it is copied verbatim into the regular
90# expression, leading to '.*=.{1,${:U2}}$'.
91#
92# Before var.c 1.856 from 2021-03-14, this regular expression was then
93# compiled even though that was not necessary for checking the syntax at the
94# level of variable expressions.  The unexpanded '$' then resulted in a wrong
95# error message.
96#
97# This only happened in lint mode since in default mode the early check for
98# unclosed expressions and unknown modifiers is skipped.
99#
100# See VarCheckSyntax, ApplyModifier_Regex.
101#
102VARMOD_REGEX=	${:UA=111 B=222 C=33:C/.*=.{1,${:U2}}$//g}
103