* lib/autoconf/lang.m4 (AC_LANG_DEFINES_PROVIDED): New macro. (AC_LANG_SOURCE): Call it. (AC_LANG_CONFTEST): Add warning if new macro is not called. * lib/autoconf/c.m4 (_AC_LANG_OPENMP): Add missing AC_LANG_SOURCE. * lib/autoconf/fortran.m4 (AC_FC_FREEFORM, AC_FC_FIXEDFORM) (AC_FC_LINE_LENGTH, __AC_FC_NAME_MANGLING): Intentionally bypass AC_LANG_SOURCE. * lib/autoconf/programs.m4 (_AC_PROG_LEX_YYTEXT_DECL): Likewise. * tests/compile.at (AC_COMPILE_IFELSE): New test. * doc/autoconf.texi (Generating Sources) <AC_LANG_CONFTEST>: Document new warning. <AC_LANG_DEFINES_PROVIDED>: Document new macro. <AC_LANG_SOURCE>: Documet use of new macro. * NEWS: Document the improvement. Suggested by Bruno Haible.
Signed-off-by: Eric Blake <ebl...@redhat.com> --- It works - it found bugs in autoconf's own (mis-)use of AC_COMPILE_IFELSE! Now to see how many other people start complaining about the new warning. ChangeLog | 17 +++++++++++++++++ NEWS | 7 +++++++ doc/autoconf.texi | 22 +++++++++++++++++++++- lib/autoconf/c.m4 | 2 +- lib/autoconf/fortran.m4 | 16 ++++++++-------- lib/autoconf/lang.m4 | 14 ++++++++++++-- lib/autoconf/programs.m4 | 7 ++++--- tests/compile.at | 44 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 114 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6ff1bc3..9c12adf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2010-08-26 Eric Blake <ebl...@redhat.com> + autoconf: warn if AC_*_IFELSE lacks complete program + * lib/autoconf/lang.m4 (AC_LANG_DEFINES_PROVIDED): New macro. + (AC_LANG_SOURCE): Call it. + (AC_LANG_CONFTEST): Add warning if new macro is not called. + * lib/autoconf/c.m4 (_AC_LANG_OPENMP): Add missing AC_LANG_SOURCE. + * lib/autoconf/fortran.m4 (AC_FC_FREEFORM, AC_FC_FIXEDFORM) + (AC_FC_LINE_LENGTH, __AC_FC_NAME_MANGLING): Intentionally bypass + AC_LANG_SOURCE. + * lib/autoconf/programs.m4 (_AC_PROG_LEX_YYTEXT_DECL): Likewise. + * tests/compile.at (AC_COMPILE_IFELSE): New test. + * doc/autoconf.texi (Generating Sources) <AC_LANG_CONFTEST>: + Document new warning. + <AC_LANG_DEFINES_PROVIDED>: Document new macro. + <AC_LANG_SOURCE>: Documet use of new macro. + * NEWS: Document the improvement. + Suggested by Bruno Haible. + autoconf: fix regression in AC_FUNC_SELECT_ARGTYPES * lib/autoconf/functions.m4 (AC_FUNC_SELECT_ARGTYPES): Fix quoting; regression from yesteray leaked '' into default value. diff --git a/NEWS b/NEWS index 3c0aed3..9998ab7 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,13 @@ GNU Autoconf NEWS - User visible changes. ** AC_INIT again allows URLs with '?' for its BUG-REPORT argument. Regression introduced in 2.66. +** The macros AC_PREPROC_IFELSE, AC_COMPILE_IFELSE, AC_LINK_IFELSE, and + AC_RUN_IFELSE now warn if the first argument failed to use + AC_LANG_SOURCE or AC_LANG_PROGRAM to generate the conftest file + contents. A new macro AC_LANG_DEFINES_PROVIDED exists if you have + a compelling reason why you cannot use AC_LANG_SOURCE but must + avoid the warning. + * Major changes in Autoconf 2.67 (2010-07-21) [stable] Released by Eric Blake, based on git versions 2.66.*. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 98dafa9..9f0e5d2 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -8730,12 +8730,32 @@ Generating Sources Note that the @var{source} is evaluated exactly once, like regular Autoconf macro arguments, and therefore (i) you may pass a macro invocation, (ii) if not, be sure to double quote if needed. + +This macro issues a warning during @command{autoconf} processing if +...@var{source} does not include an expansion of the macro +...@code{ac_lang_defines_provided} (note that both @code{AC_LANG_SOURCE} and +...@code{ac_lang_program} call this macro, and thus avoid the warning). + +This macro is seldom called directly, but is used under the hood by more +common macros such as @code{AC_COMPILE_IFELSE} and @code{AC_RUN_IFELSE}. +...@end defmac + +...@defmac AC_LANG_DEFINES_PROVIDED +...@acindex{lang_defines_provided} +This macro is called as a witness that the file +...@file{conftest.@var{extension}} appropriate for the current language is +complete, including all previously determined results from +...@code{ac_define}. This macro is seldom called directly, but exists if +you have a compelling reason to write a conftest file without using +...@code{ac_lang_source}, but still want to avoid a syntax warning from +...@code{ac_lang_conftest}. @end defmac @defmac AC_LANG_SOURCE (@var{source}) @acindex{LANG_SOURCE} Expands into the @var{source}, with the definition of -all the @code{AC_DEFINE} performed so far. +all the @code{AC_DEFINE} performed so far. This macro includes an +expansion of @code{AC_LANG_DEFINES_PROVIDED}. @end defmac For instance executing (observe the double quotation!): diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4 index 9a28adf..233644a 100644 --- a/lib/autoconf/c.m4 +++ b/lib/autoconf/c.m4 @@ -1930,7 +1930,7 @@ AC_DEFUN([AC_C_TYPEOF], # Expands to some language dependent source code for testing the presence of # OpenMP. AC_DEFUN([_AC_LANG_OPENMP], -[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) +[AC_LANG_SOURCE([_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])]) # _AC_LANG_OPENMP(C) # ------------------ diff --git a/lib/autoconf/fortran.m4 b/lib/autoconf/fortran.m4 index 0a487ee..5e48468 100644 --- a/lib/autoconf/fortran.m4 +++ b/lib/autoconf/fortran.m4 @@ -897,13 +897,13 @@ AC_DEFUN([__AC_FC_NAME_MANGLING], [_AC_FORTRAN_ASSERT()dnl AC_CACHE_CHECK([for _AC_LANG name-mangling scheme], ac_cv_[]_AC_LANG_ABBREV[]_mangling, -[AC_COMPILE_IFELSE( +[AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED [ subroutine foobar() return end subroutine foo_bar() return - end], + end]], [mv conftest.$ac_objext cfortran_test.$ac_objext ac_save_LIBS=$LIBS @@ -1186,12 +1186,12 @@ for ac_flag in none -ffree-form -FR -free -qfree -Mfree -Mfreeform \ do test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_freeform_FCFLAGS_save $ac_flag" dnl Use @&t@ below to ensure that editors don't turn 8+ spaces into tab. - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[ program freeform ! FIXME: how to best confuse non-freeform compilers? print *, 'Hello ', & @&t@ 'world.' - end], + end]], [ac_cv_fc_freeform=$ac_flag; break]) done rm -f conftest.err conftest.$ac_objext conftest.$ac_ext @@ -1241,10 +1241,10 @@ for ac_flag in none -ffixed-form -fixed -qfixed -Mfixed -fixedform "-f fixed" \ +source=fixed -fix do test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_fixedform_FCFLAGS_save $ac_flag" - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[ C This comment should confuse free-form compilers. program main - end], + end]], [ac_cv_fc_fixedform=$ac_flag; break]) done rm -f conftest.err conftest.$ac_objext conftest.$ac_ext @@ -1324,8 +1324,8 @@ for ac_flag in none \ "-W $ac_fc_line_len" +extend_source -wide -e do test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_line_length_FCFLAGS_save $ac_flag" - AC_COMPILE_IFELSE([$ac_fc_line_length_test - end subroutine], + AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[$ac_fc_line_length_test + end subroutine]], [ac_cv_fc_line_length=$ac_flag; break]) done rm -f conftest.err conftest.$ac_objext conftest.$ac_ext diff --git a/lib/autoconf/lang.m4 b/lib/autoconf/lang.m4 index 3e8de53..997b4e6 100644 --- a/lib/autoconf/lang.m4 +++ b/lib/autoconf/lang.m4 @@ -192,7 +192,10 @@ m4_define([AC_LANG_DEFINE], # ---------------------- # Save the BODY in `conftest.$ac_ext'. Add a trailing new line. AC_DEFUN([AC_LANG_CONFTEST], -[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) +[m4_pushdef([_AC_LANG_DEFINES_PROVIDED], + [m4_warn([syntax], [$0: no AC_LANG_SOURCE call detected in body])])]dnl +[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]dnl +[[]_AC_LANG_DEFINES_PROVIDED[]_m4_popdef([_AC_LANG_DEFINES_PROVIDED])]) # AC_LANG_CONFTEST()(BODY) @@ -203,13 +206,20 @@ m4_define([AC_LANG_CONFTEST()], $1 _ACEOF]) +# AC_LANG_DEFINES_PROVIDED +# ------------------------ +# Witness macro that all prior AC_DEFINE results have been output +# into the current expansion, to silence warning from AC_LANG_CONFTEST. +m4_define([AC_LANG_DEFINES_PROVIDED], +[m4_define([_$0])]) + # AC_LANG_SOURCE(BODY) # -------------------- # Produce a valid source for the current language, which includes the # BODY, and as much as possible `confdefs.h'. AC_DEFUN([AC_LANG_SOURCE], -[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) +[AC_LANG_DEFINES_PROVIDED[]_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) # AC_LANG_SOURCE()(BODY) diff --git a/lib/autoconf/programs.m4 b/lib/autoconf/programs.m4 index 4b9060f..e7eeb6f 100644 --- a/lib/autoconf/programs.m4 +++ b/lib/autoconf/programs.m4 @@ -756,7 +756,8 @@ if test -z "${LEXLIB+set}"; then ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" - AC_LINK_IFELSE([`cat $LEX_OUTPUT_ROOT.c`], [ac_cv_lib_lex=$ac_lib]) + AC_LINK_IFELSE([AC_LANG_DEFINES_PROVIDED[`cat $LEX_OUTPUT_ROOT.c`]], + [ac_cv_lib_lex=$ac_lib]) test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS @@ -772,9 +773,9 @@ AC_CACHE_CHECK(whether yytext is a pointer, ac_cv_prog_lex_yytext_pointer, ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" -AC_LINK_IFELSE( +AC_LINK_IFELSE([AC_LANG_DEFINES_PROVIDED [#define YYTEXT_POINTER 1 -`cat $LEX_OUTPUT_ROOT.c`], +`cat $LEX_OUTPUT_ROOT.c`]], [ac_cv_prog_lex_yytext_pointer=yes]) LIBS=$ac_save_LIBS ]) diff --git a/tests/compile.at b/tests/compile.at index 6a1092b..dd7175b 100644 --- a/tests/compile.at +++ b/tests/compile.at @@ -260,11 +260,55 @@ fputs (hw, stdout); AT_CLEANUP +## ------------------- ## +## AC_COMPILE_IFELSE. ## +## ------------------- ## + +AT_SETUP([AC_COMPILE_IFELSE]) +AT_KEYWORDS([AC_LANG_DEFINES_PROVIDED]) + +AT_DATA([configure.ac], +[[AC_INIT +AC_COMPILE_IFELSE([int main () { return 0; }], [], + [AC_MSG_ERROR([compiling trivial program failed])]) +]]) + +AT_CHECK_AUTOCONF([], [], [], [stderr]) +AT_CHECK([grep 'no AC_LANG_SOURCE call detected in body' stderr], [], [ignore]) +AT_CHECK_AUTOCONF([-W no-syntax]) +AT_CHECK_CONFIGURE([-q]) + +AT_DATA([configure.ac], +[[AC_INIT +AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED()int main () { return 0; }], [], + [AC_MSG_ERROR([compiling trivial program failed])]) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([-q]) + +AT_DATA([configure.ac], +[[AC_INIT +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 0])], + [], + [AC_MSG_ERROR([compiling `return 0' failed])]) + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 2])], + [], + [AC_MSG_ERROR([compiling `return 2' failed])]) +]]) + +AT_CHECK_AUTOCONF +AT_CHECK_CONFIGURE([-q]) + +AT_CLEANUP + ## --------------- ## ## AC_RUN_IFELSE. ## ## --------------- ## AT_SETUP([AC_RUN_IFELSE]) +AT_KEYWORDS([AC_TRY_RUN]) AT_DATA([configure.ac], [[AC_INIT -- 1.7.2.2