[PATCH 2/2] Warn if AC_INIT or AC_OUTPUT are missing from configure.ac (#107986)

Zack Weinberg <[email protected]>
Newsgroups gmane.comp.sysutils.autoconf.patches
Message-ID <[email protected]>
It is almost always incorrect for a configure script to omit either
AC_INIT or AC_OUTPUT.  Issue warnings in the ‘syntax’ category for
this.

The implementation is, unfortunately, a bit of a kludge.  To check for
the _absence_ of a macro invocation, we can use m4_provide_if inside a
m4_wrap hook.  However, if we activate the m4_wrap hook directly from
general.m4, we get spurious warnings at freeze time.  We also get
warnings whenever a script that’s missing AC_INIT and/or AC_OUTPUT
is *traced*, which means we get double warnings from autoconf, and
autoheader and aclocal complain about it too, which seems unnecessary.

A clean way to deal with this would be to make the hook look for a
special macro that’s defined only when autoconf (the program) is
invoked without any --trace arguments.  Unfortunately, autom4te
doesn’t pass --define down to M4, and changing that would involve
coordinating with Automake (the project), so instead I’ve gone for the
kludge: a new file lib/autoconf/trailer.m4 that calls m4_wrap.  This
file is *not* included in autoconf.m4f, but it’s installed, and it’s
added to the m4 invocation by autoconf (the program) only when not
tracing.  (It still uses m4_wrap, because we pass it to m4 *before*
configure.ac, because otherwise we get nonsense locations for any
*other* diagnostics coming out of this autoconf invocation.  I don’t
know why.)

The additional checks in autoreconf are intended to make sure that if
autoreconf skips a directory entirely, you get told why.

Lots of tests in the testsuite didn’t bother with AC_OUTPUT, and
somewhat fewer didn’t bother with AC_INIT; where possible I just added
them.

Suggested by David A. Wheeler, who submitted a patch, but I didn’t
wind up using any of his code.  (His implementation used an extra
tracing pass, only checked for a missing AC_INIT, and invented a new
command-line option to turn off this specific warning.  I thought this
was tidier overall, despite the kludge.)

* lib/autoconf/general.m4 (_AC_FINALIZE): New macro: code to be run
  when generating configure, after the entire configure.ac is
  processed. Currently only checks that AC_INIT and AC_OUTPUT were
  called at some point, issuing syntax-category warnings if not.
  (AC_INIT, AC_OUTPUT): m4_provide self.
* lib/autoconf/trailer.m4: New file that just calls m4_wrap([_AC_FINALIZE]).
* lib/local.mk: Install new file.

* bin/autoconf.as: Add trailer.m4 to the final invocation of autom4te,
  but only when not tracing.
* bin/autoreconf.in (autoreconf_current_directory): Distinguish in
  diagnostics between “directory skipped because it doesn’t have a
  configure.ac or configure.in” (e.g. Cygnus configure) and “directory
  has a configure.ac but it doesn’t appear to be autoconf input.”

* tests/*.at: Fix all tests affected by the new warnings.
---
 NEWS                    |  3 +++
 bin/autoconf.as         | 14 +++++++++++++-
 bin/autoreconf.in       | 14 ++++++++++----
 lib/autoconf/general.m4 | 23 +++++++++++++++++++++++
 lib/autoconf/status.m4  |  6 ++++++
 lib/autoconf/trailer.m4 |  4 ++++
 lib/local.mk            |  3 ++-
 tests/base.at           | 33 ++++++++++++++++++++++++++-------
 tests/c.at              |  1 +
 tests/compile.at        | 26 +++++++++++++++++++++++---
 tests/m4sh.at           |  5 ++++-
 tests/semantics.at      | 12 ++++++------
 tests/tools.at          | 28 +++++++++++++++++++++++-----
 tests/torture.at        | 13 ++++++++-----
 tests/wrapper.as        |  3 ++-
 15 files changed, 154 insertions(+), 34 deletions(-)
 create mode 100644 lib/autoconf/trailer.m4

diff --git a/NEWS b/NEWS
index e0cdd069..ccf0f40a 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,9 @@ GNU Autoconf NEWS - User visible changes.
 ** The use of the long-deprecated name 'configure.in' for the autoconf
    input file now elicits a warning in the 'obsolete' category.
 
+** autoconf will now issue warnings (in the ‘syntax’ category) if the
+   input file is missing a call to AC_INIT and/or AC_OUTPUT.
+
 ** Older version of automake and aclocal (< 1.8) are no longer supported
    by autoreconf.
 
diff --git a/bin/autoconf.as b/bin/autoconf.as
index 581eb81e..ab6e3c52 100644
--- a/bin/autoconf.as
+++ b/bin/autoconf.as
@@ -85,6 +85,7 @@ exit_missing_arg='
 
 # Variables.
 : ${AUTOM4TE='@bindir@/@autom4te-name@'}
+: ${trailer_m4='@pkgdatadir@/autoconf/trailer.m4'}
 autom4te_options=
 outfile=
 verbose=false
@@ -183,9 +184,20 @@ esac
 # Unless specified, the output is stdout.
 test -z "$outfile" && outfile=-
 
+# Don't read trailer.m4 if we are tracing.
+if test -n "$traces"; then
+    trailer_m4=""
+else
+    # The extra quotes will be stripped by eval.
+    trailer_m4=\""$trailer_m4"\"
+fi
+
 # Run autom4te with expansion.
+# trailer.m4 is read _before_ $infile, despite the name,
+# because putting it afterward screws up autom4te's location tracing.
 eval set x "$autom4te_options" \
-  --language=autoconf --output=\"\$outfile\" "$traces" \"\$infile\"
+  --language=autoconf --output=\"\$outfile\" "$traces" \
+  $trailer_m4 \"\$infile\"
 shift
 $verbose && AS_ECHO(["$as_me: running $AUTOM4TE $*"]) >&2
 exec "$AUTOM4TE" "$@"
diff --git a/bin/autoreconf.in b/bin/autoreconf.in
index 12806d3a..1ca11f28 100644
--- a/bin/autoreconf.in
+++ b/bin/autoreconf.in
@@ -245,8 +245,9 @@ sub parse_args ()
 
 # &autoreconf_current_directory
 # -----------------------------
-sub autoreconf_current_directory ()
+sub autoreconf_current_directory ($)
 {
+  my ($directory) = @_;
   my $configure_ac = find_configure_ac;
 
   # ---------------------- #
@@ -266,10 +267,15 @@ sub autoreconf_current_directory ()
 	  # See below for why we look for gettext here.
 	  $uses_gettext = 1  if /^AM_GNU_GETTEXT_VERSION/;
 	}
+      if (!$uses_autoconf)
+        {
+          error "$configure_ac: AC_INIT not found; not an autoconf script?";
+          return;
+        }
     }
-  if (!$uses_autoconf)
+  else
     {
-      verb "$configure_ac: not using Autoconf";
+      verb "neither configure.ac nor configure.in present in $directory";
       return;
     }
 
@@ -598,7 +604,7 @@ sub autoreconf ($)
   chdir $directory
     or error "cannot chdir to $directory: $!";
 
-  autoreconf_current_directory;
+  autoreconf_current_directory ($directory);
 
   # The format is not free: taken from Emacs, itself using GNU Make's
   # format.
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 4d5f021d..81360b78 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -1477,9 +1477,32 @@ _AC_ARG_VAR_PRECIOUS([host_alias])AC_SUBST([host_alias])dnl
 _AC_ARG_VAR_PRECIOUS([target_alias])AC_SUBST([target_alias])dnl
 dnl
 AC_LANG_PUSH(C)
+dnl
+dnl Record that AC_INIT has been called.  It doesn't make sense to
+dnl AC_REQUIRE AC_INIT, but it _does_ make sense for macros to say
+dnl AC_BEFORE([self], [AC_INIT]) sometimes.  Also, _AC_FINALIZE checks
+dnl for AC_INIT having been called.
+m4_provide([AC_INIT])dnl
 ])
 
 
+# _AC_FINALIZE
+# ------------
+# Code to be run after the entire configure.ac is processed, but only
+# when generating configure.  This macro should only be called from
+# trailer.m4, which is fed to m4 after configure.ac by autoconf (the
+# program).  We don't just call m4_wrap([_AC_FINALIZE]), because then
+# it would run at freeze time and when tracing configure.ac for
+# autoheader etc.
+#
+# Currently this doesn't emit anything; it just checks that AC_INIT
+# and AC_OUTPUT were expanded at some point.  Leaving either of these
+# out of a configure script is likely to be a bug.
+m4_define([_AC_FINALIZE],
+  [m4_provide_if([AC_INIT], [],
+    [m4_warn([syntax], [AC_INIT was never used])])dnl
+   m4_provide_if([AC_OUTPUT], [],
+    [m4_warn([syntax], [AC_OUTPUT was never used])])])
 
 
 ## ------------------------------------------------------------- ##
diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index dd2cb407..2d3f92ba 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -1310,6 +1310,12 @@ AC_PROVIDE_IFELSE([AC_CONFIG_SUBDIRS], [_AC_OUTPUT_SUBDIRS()])dnl
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
   AC_MSG_WARN([unrecognized options: $ac_unrecognized_opts])
 fi
+dnl
+dnl Record that AC_OUTPUT has been called.  It doesn't make sense to
+dnl AC_REQUIRE AC_OUTPUT, but it _does_ make sense for macros to say
+dnl AC_BEFORE([self], [AC_OUTPUT]).  Also, _AC_FINALIZE checks
+dnl for AC_OUTPUT having been called.
+m4_provide([AC_OUTPUT])dnl
 ])# AC_OUTPUT
 
 
diff --git a/lib/autoconf/trailer.m4 b/lib/autoconf/trailer.m4
new file mode 100644
index 00000000..7c14cbff
--- /dev/null
+++ b/lib/autoconf/trailer.m4
@@ -0,0 +1,4 @@
+dnl This file is part of Autoconf.			-*- Autoconf -*-
+dnl This file exists solely to invoke _AC_FINALIZE at the right time.
+dnl See the definition of _AC_FINALIZE (in general.m4) for further explanation.
+m4_wrap([_AC_FINALIZE])dnl
diff --git a/lib/local.mk b/lib/local.mk
index 9612a14c..5cc9d44a 100644
--- a/lib/local.mk
+++ b/lib/local.mk
@@ -97,7 +97,8 @@ dist_autoconflib_DATA = \
   lib/autoconf/headers.m4 \
   lib/autoconf/types.m4 \
   lib/autoconf/libs.m4 \
-  lib/autoconf/programs.m4
+  lib/autoconf/programs.m4 \
+  lib/autoconf/trailer.m4
 
 nodist_autoconflib_DATA = lib/autoconf/autoconf.m4f
 CLEANFILES += $(nodist_autoconflib_DATA)
diff --git a/tests/base.at b/tests/base.at
index 98125173..4042a8aa 100644
--- a/tests/base.at
+++ b/tests/base.at
@@ -57,7 +57,10 @@ test -z "$test1" &&
 AS_EXIT(0)
 ]])
 
-AT_CHECK_AUTOCONF
+AT_CHECK_AUTOCONF([], [0], [],
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+]])
 AT_CHECK_CONFIGURE
 
 AT_CLEANUP
@@ -117,7 +120,10 @@ case $multi_test:$single_test in
 esac
 ]])
 
-AT_CHECK_AUTOCONF([], 0, [])
+AT_CHECK_AUTOCONF([], 0, [],
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+]])
 
 AT_CHECK_CONFIGURE
 
@@ -160,7 +166,10 @@ case $multi_test:$single_test in
 esac
 ]])
 
-AT_CHECK_AUTOCONF([], 0, [])
+AT_CHECK_AUTOCONF([], 0, [],
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+]])
 AT_CHECK_CONFIGURE
 
 AT_CLEANUP
@@ -192,7 +201,10 @@ case $inner_test in
 esac
 ]])
 
-AT_CHECK_AUTOCONF
+AT_CHECK_AUTOCONF([], 0, [],
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+]])
 AT_CHECK_CONFIGURE
 
 AT_CLEANUP
@@ -208,6 +220,7 @@ AT_SETUP([AC_INIT])
 
 AT_DATA([configure.ac],
 [[AC_INIT([GNU fu], [1.0], [[email protected]])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -354,6 +367,7 @@ words that may be matched by scanners for legal things,
 causing extra work for distributors.
 Multi-line values should be supported.
 ]])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -403,8 +417,7 @@ if ${my_cv_variable+false} :; then
   AC_MSG_ERROR([AC@&@&t@t@_CACHE_VAL did not ensure that the cache variable was set])
 fi
 
-# AC_CACHE_SAVE should be enough here, no need for AC_OUTPUT.
-AC_CACHE_SAVE
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF([], [], [], [stderr])
@@ -603,6 +616,7 @@ AC_COMPUTE_INT([invalid_expression],
 	       [invalid_expression=failed])
 test "$invalid_expression" = failed ||
   AC_MSG_ERROR([**0** evaluated to $invalid_expression instead of failing])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -633,6 +647,8 @@ if AC_TRY_COMMAND([(echo "The Cat in the Hat";
 		   grep \^The\ Hat\ in\ the\ Cat\$ >/dev/null]); then
   AC_MSG_ERROR([saw the Hat in the Cat])
 fi
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -650,9 +666,10 @@ AT_SETUP([Input/Output])
 AT_DATA([configure.ac],
 [[AC_INIT
 cat <&AS@&t@_ORIGINAL_STDIN_FD >&AS@&t@_MESSAGE_FD
+AC_OUTPUT
 ]])
 AT_CHECK_AUTOCONF
-AT_CHECK([echo Hello | CONFIG_SITE=/dev/null ./configure $configure_options | grep -v 'configure: loading site script '],, [Hello
+AT_CHECK([echo Hello | CONFIG_SITE=/dev/null ./configure $configure_options | grep -v '^configure: '],, [Hello
 ])
 AT_CHECK([echo Hello | CONFIG_SITE=/dev/null ./configure $configure_options --silent])
 
@@ -668,6 +685,7 @@ AT_SETUP([configure arguments])
 AT_DATA([configure.ac],
 [[AC_INIT
 echo "$@"
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -706,6 +724,7 @@ AC_ARG_ENABLE([c++],
 echo "use_foo: $use_foo"
 echo "with_c++: $with_c__, $choice_with"
 echo "enable_c++: $enable_c__, $choice_enable"
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
diff --git a/tests/c.at b/tests/c.at
index b65d7d44..b1dabd14 100644
--- a/tests/c.at
+++ b/tests/c.at
@@ -60,6 +60,7 @@ AT_DATA([configure.ac],
 [[AC_INIT
 CC=no-such-compiler
 AC_PROG_CC
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
diff --git a/tests/compile.at b/tests/compile.at
index 5d75ada8..fbba8e63 100644
--- a/tests/compile.at
+++ b/tests/compile.at
@@ -55,6 +55,7 @@ AC_LANG_POP([C++])
 # C C
 AC_LANG_POP([C])
 # C
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -106,7 +107,10 @@ AC_F77_2
 AS_EXIT(0)
 ]])
 
-AT_CHECK_AUTOCONF
+AT_CHECK_AUTOCONF([], [0], [],
+[[trailer.m4: warning: AC_OUTPUT was never used
+]])
+
 AT_CHECK_CONFIGURE
 
 AT_CLEANUP
@@ -129,6 +133,7 @@ int main (void)
   return 0;
 }
 ]], [], [AC_MSG_FAILURE([confdefs not included])])])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -155,6 +160,7 @@ int main (void)
   return 0;
 }
 ]], [], [AC_MSG_FAILURE([confdefs not included])])])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -185,6 +191,7 @@ AC_LANG([C])
 AC_LANG_CONFTEST(
    [AC_LANG_SOURCE([[const char hw[] = "Hello, World\n";]])])
 gcc -E -dD conftest.c || AS_EXIT([77])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -193,7 +200,7 @@ AT_CHECK_CONFIGURE([], [], [stdout])
 # Note that the output may contain more defines and lines matching
 #   # 1 "conftest.c"
 # so delete everything before the interesting output.
-AT_CHECK([sed -n 's/ *$//; /#define PACKAGE/,$p' stdout], [],
+AT_CHECK([sed -n 's/ *$//; /^configure: /d; /#define PACKAGE/,$p' stdout], [],
 [[#define PACKAGE_NAME "Hello"
 #define PACKAGE_TARNAME "hello"
 #define PACKAGE_VERSION "1.0"
@@ -230,6 +237,7 @@ AC_LANG_CONFTEST(
 [AC_LANG_PROGRAM([[const char hw[] = "Hello, World\n";]],
                  [[fputs (hw, stdout);]])])
 gcc -E -dD conftest.c || AS_EXIT([77])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -238,7 +246,7 @@ AT_CHECK_CONFIGURE([], [], [stdout])
 # Note that the output may contain more defines and lines matching
 #   # 1 "conftest.c"
 # so delete everything before the interesting output.
-AT_CHECK([sed -n 's/ *$//; /#define PACKAGE/,$p' stdout], [],
+AT_CHECK([sed -n 's/ *$//; /^configure: /d; /#define PACKAGE/,$p' stdout], [],
 [[#define PACKAGE_NAME "Hello"
 #define PACKAGE_TARNAME "hello"
 #define PACKAGE_VERSION "1.0"
@@ -271,6 +279,7 @@ AT_DATA([configure.ac],
 [[AC_INIT
 AC_COMPILE_IFELSE([int main (void) { return 0; }], [],
   [AC_MSG_ERROR([compiling trivial program failed])])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF([], [], [], [stderr])
@@ -282,6 +291,7 @@ AT_DATA([configure.ac],
 [[AC_INIT
 AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED()int main (void) { return 0; }], [],
   [AC_MSG_ERROR([compiling trivial program failed])])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -296,6 +306,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 0])],
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 2])],
 	      [],
 	      [AC_MSG_ERROR([compiling `return 2' failed])])
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -330,6 +341,7 @@ AC_TRY_RUN([int main (void) { return 3; }],
 test $estatus != 3 &&
   AC_MSG_ERROR([did not get 3 as exit status: $estatus])])
 
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -375,6 +387,8 @@ d@&t@nl conftest.err not generated by AC_RUN_IFELSE?
 AC_RUN_IFELSE([AC_LANG_PROGRAM([int bad bad;], [])],
 	      [AS_EXIT([1])],
 	      [])
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -410,6 +424,8 @@ AC_COMPILE_IFELSE([
     choke me
     #endif
   ]])], [], AS_EXIT([77]))
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -428,6 +444,8 @@ AC_COMPILE_IFELSE([
     #endif
   ]])], [], AS_EXIT([77]))
 AC_LANG_POP([C++])
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -457,6 +475,8 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([class A {};], [])],
 
 AC_CHECK_HEADER([cstring])
 AC_LANG_POP([C++])
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
diff --git a/tests/m4sh.at b/tests/m4sh.at
index a18277ac..b352704d 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -112,6 +112,7 @@ AT_SETUP([Configure re-execs self with CONFIG_SHELL])
 AT_DATA([configure.ac],
 [[AC_INIT
 echo foobar >> quux
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -127,7 +128,9 @@ AT_CAPTURE_FILE([config.log])
 # Export CONFIG_SITE to /dev/null to avoid spurious diffs in expected
 # stdout/stderr.
 AT_CHECK([env CONFIG_SITE=/dev/null CONFIG_SHELL=./cfg-sh ./configure],
-         [0], [], [])
+         [0],
+[[configure: creating ./config.status
+]], [])
 # ./configure re-executed itself.
 AT_CHECK([test -f cfg-sh-has-run], [0])
 # And did that not to cause extra execution of later commands.
diff --git a/tests/semantics.at b/tests/semantics.at
index f10a0b53..98933aa1 100644
--- a/tests/semantics.at
+++ b/tests/semantics.at
@@ -589,10 +589,10 @@ test -z "$TOOL5" || fail=:
 AC_CHECK_PROGS(TOOL6, missing tool better,, $path)
 test "$TOOL6" = tool || fail=:
 
-# No AC-OUTPUT, we don't need config.status.
 $fail &&
   AC_MSG_ERROR([[CHECK_PROG failed]])
-AS_EXIT(0)
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -692,10 +692,10 @@ test -z "$TOOL3" || fail=:
 AC_PATH_PROGS(TOOL4, missing tool better,, $path)
 test "$TOOL4" = "$pwd/path/1/tool" || fail=:
 
-# No AC-OUTPUT, we don't need config.status.
 $fail &&
   AC_MSG_ERROR([[PATH_PROG failed]])
-AS_EXIT(0)
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
@@ -770,10 +770,10 @@ AC_PATH_PROGS_FEATURE_CHECK(TOOL7, [tool better],
 test -z "$TOOL7" || fail=:
 test "$ac_cv_path_TOOL7" = "$pwd/path/1/tool" || fail=:
 
-# No AC-OUTPUT, we don't need config.status.
 $fail &&
   AC_MSG_ERROR([[PATH_PROG failed]])
-AS_EXIT(0)
+
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
diff --git a/tests/tools.at b/tests/tools.at
index 314462ff..3093225c 100644
--- a/tests/tools.at
+++ b/tests/tools.at
@@ -390,6 +390,7 @@ AT_DATA([configure.ac],
 [[AC_INIT
 AC_CONFIG_MACRO_DIR([dir1])
 AC_CONFIG_MACRO_DIR([dir2])
+AC_OUTPUT
 ]])
 AT_CHECK_AUTOCONF([], [1], [], [stderr])
 AT_CHECK([grep 'error: AC_CONFIG_MACRO_DIR can only be used once' stderr],
@@ -421,6 +422,7 @@ AT_DATA([configure.ac],
 [[AC_INIT
 AC_CONFIG_MACRO_DIRS([dir1])
 AC_CONFIG_MACRO_DIRS([dir2])
+AC_OUTPUT
 ]])
 AT_CHECK_AUTOCONF([], [0], [], [])
 AT_CHECK_AUTOCONF([-t AC_CONFIG_MACRO_DIR], [0],
@@ -459,7 +461,9 @@ end-language: "Autoconf-without-aclocal-m4"
 ]])
 
 AT_CHECK_AUTOCONF([], 1, [],
-[[configure.ac:2: error: possibly undefined macro: m4@&t@_foo
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+configure.ac:2: error: possibly undefined macro: m4@&t@_foo
       If this token and others are legitimate, please use m4@&t@_pattern_allow.
       See the Autoconf documentation.
 configure.ac:3: error: possibly undefined macro: _m4@&t@_bar
@@ -467,8 +471,12 @@ configure.ac:4: error: possibly undefined macro: AS@&t@_FOO
 configure.ac:5: error: possibly undefined macro: _AS@&t@_BAR
 configure.ac:6: error: possibly undefined macro: d@&t@nl
 ]])
-# Second run should succeed and yield no output.
-AT_CHECK([autoconf])
+# A second run (without --force) should succeed and yield only the
+# warnings about AC_INIT and AC_OUTPUT.
+AT_CHECK_M4([autoconf], 0, [],
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+]])
 
 AT_CLEANUP
 
@@ -500,7 +508,9 @@ It would be very bad if Autoconf forgot to expand [AS_]INIT!
 ]])
 
 AT_CHECK_AUTOCONF([], 1, [],
-[[configure.ac:1: error: possibly undefined macro: AS@&t@_INIT
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+configure.ac:1: error: possibly undefined macro: AS@&t@_INIT
       If this token and others are legitimate, please use m4@&t@_pattern_allow.
       See the Autoconf documentation.
 configure.ac:7: error: possibly undefined macro: AS@&t@_ALLOWED_NOT
@@ -539,7 +549,10 @@ m4_divert([])dnl
  line that begins with a space
 ]])
 
-AT_CHECK_AUTOCONF
+AT_CHECK_AUTOCONF([], 0, [],
+[[trailer.m4: warning: AC_INIT was never used
+trailer.m4: warning: AC_OUTPUT was never used
+]])
 
 AT_CLEANUP
 
@@ -1009,6 +1022,7 @@ AT_DATA([configure.ac],
 [[AC_INIT
 OLD(1, 2)
 NEW([0, 0], [0])
+AC_OUTPUT
 ]])
 
 # Checking `autoupdate'.
@@ -1053,6 +1067,7 @@ AT_SETUP([autoupdating AC_HELP_STRING])
 AT_DATA([configure.ac],
 [[AC_INIT
 AC_ARG_ENABLE([foo], [AC_HELP_STRING([--enable-foo], [foo bar])], [:], [:])
+AC_OUTPUT
 ]])
 
 # Checking `autoupdate'.
@@ -1189,6 +1204,7 @@ AC_LANG_SAVE
 AC_LANG_RESTORE
 AC_LANG_SAVE
 AC_LANG_RESTORE
+AC_OUTPUT
 ]])
 
 # Checking `autoupdate'.
@@ -1210,6 +1226,7 @@ AT_DATA([aclocal.m4],
 AT_DATA([configure.ac],
 [[AC_INIT
 echo AC_FOREACH([myvar], [1 2 3], [' myvar'])OLD
+AC_OUTPUT
 ]])
 
 # Checking `autoupdate'.
@@ -1318,6 +1335,7 @@ chmod a-w sub
 
 AT_DATA([configure.ac],
 [[AC_INIT
+AC_OUTPUT
 ]])
 
 AT_DATA([.autom4te.cfg],
diff --git a/tests/torture.at b/tests/torture.at
index b50dfebc..37deef25 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -1037,12 +1037,12 @@ two], [This spans two lines.])
 AT_CHECK_AUTOCONF([], [], [], [stderr])
 dnl Older versions of m4 report error at line 5 (end of macro);
 dnl newer versions report it at line 4 (start of macro).
-AT_CHECK([[sed 's/^configure.ac:[45]: //' stderr]], [],
+AT_CHECK([[sed '/trailer\.m4:/d; s/^configure\.ac:[45]: //' stderr]], [],
 [[warning: AC_DEFINE: `one
 two' is not a valid preprocessor define value
 ]])
 AT_CHECK_AUTOHEADER([], [foo], [], [], [stderr])
-AT_CHECK([[sed 's/^configure.ac:[45]: //' stderr]], [],
+AT_CHECK([[sed 's/^configure\.ac:[45]: //' stderr]], [],
 [[warning: AC_DEFINE: `one
 two' is not a valid preprocessor define value
 ]])
@@ -1050,16 +1050,18 @@ AT_CHECK_CONFIGURE
 AT_CHECK_DEFINES([[#define foo one
 ]])
 
+rm -rf autom4te.cache
+
 AT_CONFIGURE_AC([[AC_DEFINE_UNQUOTED([foo], [one
 two], [This spans two lines.])
 ]])
 AT_CHECK_AUTOCONF([], [], [], [stderr])
-AT_CHECK([[sed 's/^configure.ac:[45]: //' stderr]], [],
+AT_CHECK([[sed '/trailer.m4:/d; s/^configure\.ac:[45]: //' stderr]], [],
 [[warning: AC_DEFINE_UNQUOTED: `one
 two' is not a valid preprocessor define value
 ]])
 AT_CHECK_AUTOHEADER([], [foo], [], [], [stderr])
-AT_CHECK([[sed 's/^configure.ac:[45]: //' stderr]], [],
+AT_CHECK([[sed 's/^configure\.ac:[45]: //' stderr]], [],
 [[warning: AC_DEFINE_UNQUOTED: `one
 two' is not a valid preprocessor define value
 ]])
@@ -1290,10 +1292,11 @@ AT_DATA([configure.ac],
 [[AC_INIT
 kill -2 $$
 exit 77
+AC_OUTPUT
 ]])
 
 AT_CHECK_AUTOCONF
-AT_CHECK_CONFIGURE([], 1, ignore, ignore)
+AT_CHECK_CONFIGURE([], [1], [ignore], [ignore])
 
 AT_CLEANUP
 
diff --git a/tests/wrapper.as b/tests/wrapper.as
index 8f77053e..f0a5c037 100644
--- a/tests/wrapper.as
+++ b/tests/wrapper.as
@@ -24,7 +24,8 @@ AUTOHEADER=autoheader
 AUTOM4TE=autom4te
 AUTOM4TE_CFG='@abs_top_builddir@/lib/autom4te.cfg'
 autom4te_perllibdir='@abs_top_srcdir@/lib'
-export AUTOCONF AUTOHEADER AUTOM4TE AUTOM4TE_CFG autom4te_perllibdir
+trailer_m4='@abs_top_srcdir@/lib/autoconf/trailer.m4'
+export AUTOCONF AUTOHEADER AUTOM4TE AUTOM4TE_CFG autom4te_perllibdir trailer_m4
 
 case '@wrap_program@' in
   ifnames)
-- 
2.28.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.