[cfe-dev] gcc compatibility: error: number of arguments doesn't match prototype

Afriza N. Arief afriza.na at gmail.com
Fri Apr 6 01:35:39 PDT 2012


On Fri, Mar 30, 2012 at 9:21 AM, Eli Friedman <eli.friedman at gmail.com> wrote:
>
> On Thu, Mar 29, 2012 at 5:21 PM, Afriza N. Arief <afriza.na at gmail.com>
> wrote:
> > On Fri, Mar 30, 2012 at 5:55 AM, Eli Friedman <eli.friedman at gmail.com>
> > wrote:
> >>
> >> On Sat, Mar 17, 2012 at 4:19 AM, Afriza N. Arief <afriza.na at gmail.com>
> >> wrote:
> >> > void taskmain(int argc, char* argv[]);
> >> >
> >> > void taskmain() {
> >> >   printf("libtask");
> >> > }
> >> >
> >> > Hello,
> >> >
> >> > for the above code, gcc reports error and clang -std=gnu89 keeps
> >> > quiet.
> >> >
> >> > is this intentional?
> >>
> >> Not intentional... we really ought to be at least printing a warning
> >> here.  Please file at http://llvm.org/bugs/ .
> >
> > Thank you, filed at http://llvm.org/bugs/show_bug.cgi?id=12414
> >
> > Any pointers roughly where in the code this can fixed?
>
> Try Sema::MergeFunctionDecl in SemaDecl.cpp .
>
> -Eli

Hello,

The way gcc handles the number of parameters is strange:
(1)
void abc(int a);
void abc() {}
int main() {}
=> gcc produces:
af.c: In function ‘abc’:
af.c:2:1: error: number of arguments doesn’t match prototype
af.c:1:6: error: prototype declaration
=> clang compiles successfully. the attached patch changes this to a warning

(2)
void abc();
void abc(int a) {}
int main() {}
=> gcc compiles successfully!
=> clang compiles successfully

(3) for both
(3a)
void abc(int a, int b);
void abc(int a) {}
int main() {}
(3b)
void abc(int a);
void abc(int a, int b) {}
int main() {}
=> gcc produces
af.c:2:6: error: conflicting types for ‘abc’
af.c:1:6: note: previous declaration of ‘abc’ was here
=> clang produces
af.c:2:6: error: conflicting types for 'abc'
void abc(int a) {}
    ^
af.c:1:6: note: previous declaration is here
void abc(int a, int b);
    ^
1 error generated.

And so, here is my first attempt

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td
b/include/clang/Basic/DiagnosticSemaKinds.td
index 30173fb..7ab3a9b 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -181,6 +181,10 @@ def ext_implicit_function_decl : ExtWarn<
  InGroup<ImplicitFunctionDeclare>;
def note_function_suggestion : Note<"did you mean %0?">;

+def warn_prototype_args_mismatch : Warning<
+  "GCC does not allow function definition to have different number "
+  "of arguments than the prototype">, InGroup<GccCompat>;
+
def err_ellipsis_first_arg : Error<
  "ISO C requires a named argument before '...'">;
def err_declarator_need_ident : Error<"declarator requires an identifier">;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 12b9a63..07ff5b7 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1955,6 +1955,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New,
Decl *OldD, Scope *S) {
    // Fall through for conflicting redeclarations and redefinitions.
  }

+  if (!getLangOpts().CPlusPlus && getLangOpts().GNUMode &&
+      Old->getNumParams() > 0 && New->getNumParams() == 0) {
+    Diag(New->getLocation(), diag::warn_prototype_args_mismatch);
+    Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+  }
+
  // C: Function types need to be compatible, not identical. This handles
  // duplicate function decls like "void f(int); void f(enum X);" properly.
  if (!getLangOpts().CPlusPlus &&




More information about the cfe-dev mailing list