autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: preparation for expand-before-require warning


From: Eric Blake
Subject: Re: preparation for expand-before-require warning
Date: Thu, 22 Jan 2009 15:16:03 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> > > Libtool uses an idiom that is now warned about.

> The problem is that the presence of d requiring c was enough to make b 
> requiring a think it was in a nested require situation.  So it looks like I 
> need to be a bit more careful about detecting expand-before-require, perhaps 
by 
> changing m4_provide to track which diversion a macro was provided in, rather 
> than its current usage of a binary check of whether it is provided at all.
> 
> I'm still thinking about the solution, but I think it should be possible to 
> silence this false positive before autoconf 2.64.
> 

Done as follows:


From: Eric Blake <address@hidden>
Date: Thu, 22 Jan 2009 08:08:06 -0700
Subject: [PATCH] Silence a false positive expand-before-require case.

* lib/m4sugar/m4sugar.m4 (m4_provide): Track the diversion in
which a macro was provided.
(m4_require): Compare diversion numbers, rather than m4_require
nesting, when determining direct requires.
* tests/m4sugar.at (m4@&address@hidden: nested): Test it.
Reported by Ralf Wildenhues, affecting Libtool.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog              |   10 ++++++++++
 lib/m4sugar/m4sugar.m4 |   43 ++++++++++++++++++++++++-------------------
 tests/m4sugar.at       |   11 +++++++++++
 3 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4ac83f5..f4bc206 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-01-22  Eric Blake  <address@hidden>
+
+       Silence a false positive expand-before-require case.
+       * lib/m4sugar/m4sugar.m4 (m4_provide): Track the diversion in
+       which a macro was provided.
+       (m4_require): Compare diversion numbers, rather than m4_require
+       nesting, when determining direct requires.
+       * tests/m4sugar.at (m4@&address@hidden: nested): Test it.
+       Reported by Ralf Wildenhues, affecting Libtool.
+
 2009-01-21  Eric Blake  <address@hidden>
 
        Fix out-of-order expansion with expand-before-require.
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 3a5ce49..372298f 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -1723,28 +1723,34 @@ m4_define([m4_undivert],
 #
 # The problem can only occur if a single defun'd macro first provides,
 # then later indirectly requires, the same macro.  Note that directly
-# expanding then requiring a macro is okay, since the requirement will
-# be a no-op; the problem is only present if the requirement is nested
-# inside a context that will be hoisted in front of the outermost
-# defun'd macro.  In other words, we must be careful not to warn on:
+# expanding then requiring a macro is okay, because the dependency was
+# met, the require phase will be a no-op; the out-of-order expansion
+# problem is only present if the requirement is nested inside a
+# context that will be hoisted in front of the outermost defun'd
+# macro.  In other words, we must be careful not to warn on:
 #
 # | m4_defun([TEST4], [4])
 # | m4_defun([TEST5], [TEST4 REQUIRE([TEST5])])
 #
+# So, to detect whether a require was direct or indirect, m4_provide
+# stores the diversion number at which a macro was provided.  A
+# require call is direct if it occurs within the same diversion that
+# the macro was provided.
+#
 # The implementation of the warning involves tracking the set of
 # macros which have been provided since the start of the outermost
 # defun'd macro (the set is named _m4_provide).  When starting an
 # outermost macro, the set is emptied; when a macro is provided, it is
 # added to the set; when require expands the body of a macro, it is
-# removed from the set; and when a macro is indirectly required (that
-# is, when m4_require detects a nested call), the set is checked.  If
-# a macro is in the set, then it has been provided before it was
-# required, and we satisfy dependencies by expanding the macro as if
-# it had never been provided; in the example given above, this means
-# we now output `1 2 3 1'.  Meanwhile, a warning is issued to inform
-# the user that her macros trigger the bug in older autoconf versions,
-# and that her outupt file now contains redundant contents (and
-# possibly new problems, if the repeated macro was not idempotent).
+# removed from the set; and when a macro is indirectly required, the
+# set is checked.  If a macro is in the set, then it has been provided
+# before it was required, and we satisfy dependencies by expanding the
+# macro as if it had never been provided; in the example given above,
+# this means we now output `1 2 3 1'.  Meanwhile, a warning is issued
+# to inform the user that her macros trigger the bug in older autoconf
+# versions, and that her output file now contains redundant contents
+# (and possibly new problems, if the repeated macro was not
+# idempotent).
 #
 #
 # 2. Keeping track of the expansion stack
@@ -1986,11 +1992,10 @@ m4_define([m4_require],
 [m4_if(_m4_divert_dump, [],
   [m4_fatal([$0($1): cannot be used outside of an ]dnl
 m4_if([$0], [m4_require], [[m4_defun]], [[AC_DEFUN]])['d macro])])]dnl
-[m4_provide_if([$1], [m4_ifdef([_m4_require],
-  [m4_set_contains([_m4_provide], [$1], [m4_warn([syntax],
-      [$0: `$1' was expanded before it was required])_m4_require_call],
-    [m4_ignore])], [m4_ignore])],
-  [_m4_require_call])([$1], [$2], _m4_divert_dump)])
+[m4_provide_if([$1], [m4_set_contains([_m4_provide], [$1], [m4_if(m4_divnum,
+      _m4_defn([m4_provide($1)]), [m4_ignore], [m4_warn([syntax],
+      [$0: `$1' was expanded before it was required])_m4_require_call])],
+    [m4_ignore])], [_m4_require_call])([$1], [$2], _m4_divert_dump)])
 
 
 # _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK],
@@ -2032,7 +2037,7 @@ m4_define([m4_expand_once],
 # ----------------------
 m4_define([m4_provide],
 [m4_ifdef([m4_provide($1)], [],
-[m4_set_add([_m4_provide], [$1], [m4_define([m4_provide($1)])])])])
+[m4_set_add([_m4_provide], [$1], [m4_define([m4_provide($1)], m4_divnum)])])])
 
 
 # m4_provide_if(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 613a3c9..22e7a07 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -583,6 +583,13 @@ c
 d
 post2])dnl
 outer
+m4_defun([e], [[e]])dnl
+m4_defun([f], [[f]m4_require([e])])dnl
+m4_defun([g], [[g]
+e
+f])dnl
+m4_defun([h], [[h]m4_require([g])])dnl
+h
 ]],
 [[pre1
 a
@@ -596,6 +603,10 @@ d
 c
 d
 post2
+g
+e
+f
+h
 ]])
 
 AT_CLEANUP
-- 
1.6.0.4







reply via email to

[Prev in Thread] Current Thread [Next in Thread]