Bug 33305 - We should warn about empty macro arguments
Summary: We should warn about empty macro arguments
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 4.3.0
: P3 enhancement
Target Milestone: 4.4.0
Assignee: Andrew Haley
URL:
Keywords:
Depends on: 33304
Blocks:
  Show dependency treegraph
 
Reported: 2007-09-04 16:13 UTC by Kaveh Ghazi
Modified: 2010-03-17 20:05 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kaveh Ghazi 2007-09-04 16:13:02 UTC
As noted in PR33304, empty macro arguments can cause problems for ISO C90 compilers (solaris cc) as well as for older gcc versions like 2.8.1.  Therefore I'd like to see cpp warn about these constructs either with -pedantic in C90 more and/or its own flag.

We should use this warning during bootstrap to keep the sources bootstrappable when using compilers that have this issue.  We have to fix the existing cases before we do that though.
Comment 1 Manuel López-Ibáñez 2007-09-05 09:24:09 UTC
There was talking about creating a -Wundefined flag that warns about undefined behaviour (PR30334). Would this fit in there? (-pedantic is not supposed to warn about undefined constructions as far as I know).
Comment 2 Andrew Pinski 2007-09-05 09:29:36 UTC
Subject: Re:  We should warn about empty macro arguments

On 5 Sep 2007 09:24:09 -0000, manu at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
> There was talking about creating a -Wundefined flag that warns about undefined
> behaviour (PR30334). Would this fit in there? (-pedantic is not supposed to
> warn about undefined constructions as far as I know).

There are two different undefined behaviors, one at runtime and one at
compile time.  This belongs to the latter which means we can
diagnostic this if we want (and can do it with -pedantic in fact).

-- Pinski
Comment 3 Kaveh Ghazi 2007-09-05 17:29:40 UTC
Anyone know where in the preprocessor this should be done?  I.e. which function in libcpp?

If someone would let me know, I'll write a patch.
Comment 4 Manuel López-Ibáñez 2007-11-09 02:09:34 UTC
(In reply to comment #3)
> Anyone know where in the preprocessor this should be done?  I.e. which function
> in libcpp?
> 
> If someone would let me know, I'll write a patch.
> 

This is the patch I was playing with before giving up. I don't know how to get the correct line numbers so I tried 3 possibilities.

Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c      (revision 129897)
+++ libcpp/macro.c      (working copy)
@@ -681,9 +681,39 @@ collect_args (cpp_reader *pfile, const c
     }
   else
     {
+      unsigned int i;
+
       /* A single empty argument is counted as no argument.  */
       if (argc == 1 && macro->paramc == 0 && args[0].count == 0)
        argc = 0;
+
+      for (i = 0; i < argc; i++)
+        {
+          if (args[i].count == 0
+              && CPP_OPTION (pfile, pedantic)
+              && CPP_OPTION (pfile, lang) == CLK_GNUC89)
+            {
+              if (pfile->context->prev && pfile->context->prev->macro)
+                cpp_error_with_line (pfile, CPP_DL_PEDWARN,
+                    pfile->context->prev->macro->value.macro->line, 0,
+                    "invoking  macro \"%s\" "
+                    "with empty arguments is undefined in ISO C90",
+                    NODE_NAME (node));
+              else if (pfile->context->prev || pfile->state.in_directive)
+                cpp_error_with_line (pfile, CPP_DL_PEDWARN,
+                                     node->value.macro->line, 0,
+                                     "invoking  macro \"%s\" "
+                    "with empty arguments is undefined in ISO C90",
+                    NODE_NAME (node));
+              else
+                cpp_error (pfile, CPP_DL_PEDWARN,
+                           "invoking  macro \"%s\" "
+                           "with empty arguments is undefined in ISO C90",
+                           NODE_NAME (node));
+
+          }
+        }
+
       if (_cpp_arguments_ok (pfile, macro, node, argc))
        {
          /* GCC has special semantics for , ## b where b is a varargs

And this is the testcase I am using:

/* { dg-do compile } */
/* { dg-options "-std=c90 -pedantic-errors" } */

#define f2(a,b,c) a; b; c;
#define f(a,b)   f2(a,,b) /* { dg-warning "macro "f2" with empty arguments } */
#define f3(a)    a

#define g()   0

void foo(void)
{
    f(0,0);
    f2(0,,0); /* { dg-warning "macro "f2" with empty arguments } */
    f3(); /* { dg-warning "macro "f3" with empty arguments } */
    g();
}
Comment 5 Andrew Haley 2008-07-03 10:14:32 UTC
Subject: Bug 33305

Author: aph
Date: Thu Jul  3 10:13:48 2008
New Revision: 137411

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=137411
Log:
2008-07-03  Andrew Haley  <aph@redhat.com>

        PR preprocessor/33305
        * gcc.dg/cpp/avoidpaste1.c: Use dg-options "-ansi" to avoid
        "-pedantic".
        * gcc.dg/cpp/avoidpaste2.c: Likewise
        * gcc.dg/cpp/20000519-1.c: Likewise.
        * g++.dg/ext/gnu-inline-global-reject.C: Likewise.
        * gcc.dg/cpp/c99-empty-macro-args.c: New test.
        * gcc.dg/cpp/c90-empty-macro-args.c: New test.


Added:
    trunk/gcc/testsuite/gcc.dg/cpp/c90-empty-macro-args.c
    trunk/gcc/testsuite/gcc.dg/cpp/c99-empty-macro-args.c
Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
    trunk/gcc/testsuite/gcc.dg/cpp/20000519-1.c
    trunk/gcc/testsuite/gcc.dg/cpp/avoidpaste1.c
    trunk/gcc/testsuite/gcc.dg/cpp/avoidpaste2.c

Comment 6 Andrew Haley 2008-07-03 10:32:42 UTC
Subject: Bug 33305

Author: aph
Date: Thu Jul  3 10:31:50 2008
New Revision: 137414

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=137414
Log:
2008-06-13  Andrew Haley  <aph@redhat.com>

        PR preprocessor/33305
        * macro.c (replace_args): Print a warning for empty macro
        arguments in C89 and C++.


Modified:
    trunk/libcpp/ChangeLog
    trunk/libcpp/macro.c

Comment 7 Tom Tromey 2008-07-12 17:06:47 UTC
Fixed on trunk.
Comment 8 Vadim Zeitlin 2010-03-17 20:05:12 UTC
Sorry for a late follow up but I've just discovered that this change broke
compilation of code using wxWidgets library with "-pedantic-errors -std=c++98"
switches because wxWidgets uses constructions such as (simplified):

#define wxEMPTY_PARAMETER_VALUE /* Fake macro parameter value */

/*
This will be __declspec(dllexport) for some compilers, __attribute__ ((visibility("default"))) for other ones and empty in non-shared library build
*/
#define wxEXPORT ...

#define wxDECLARE_SOMETHING(expdecl, name) class expdecl name
#define wxDECLARE_EXPORTED_SOMETHING(name) wxDECLARE_SOMETHING(wxEXPORT, name)


And now, with g++ 4.4.3 from Debian Unstable, this results in "empty macro
arguments are undefined in ISO C90 and ISO C++98" warning/error when wxEXPORT
is empty.

Admittedly, the error may be correct (although to be honest I am not even 100% sure it is even after rereading 16.3 and 16.3.1 of C++98 several times), but this use is common and often occurs in other code. Even Boost defines BOOST_PP_EMPTY in its boost/preprocessor/facilities/empty.hpp and I definitely saw this many times in other code as well so at the very least there is a widespread belief in C++ community that such usage is valid.

So ideally I'd like to see gcc behave more leniently when a macro which
expands to an empty value is passed to another macro as argument (as opposed
to directly omitting a macro argument). Failing that, it'd be nice to have a
specific option to turn this behaviour off. Because right now the only choice
seems to be to either disable -pedantic (which would be a really unfortunate
consequence of the change making gcc stricter) or use -std=c++0x which is more
acceptable but still not always desirable.

TIA!