r218166 - Follow-up to r214408: Warn on other callee-cleanup functions without prototype too.

Nico Weber nicolasweber at gmx.de
Fri Sep 19 16:07:13 PDT 2014


Author: nico
Date: Fri Sep 19 18:07:12 2014
New Revision: 218166

URL: http://llvm.org/viewvc/llvm-project?rev=218166&view=rev
Log:
Follow-up to r214408: Warn on other callee-cleanup functions without prototype too.

According to lore, we used to verifier-fail on:

  void __thiscall f();
  int main() { f(1); }

So that's fixed now. System headers use prototype-less __stdcall functions,
so make that a warning that's DefaultError -- then it fires on regular code
but is suppressed in system headers.

Since it's used in system headers, we have codegen tests for this; massage
them slightly so that they still compile.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CodeGen/mangle-windows.c
    cfe/trunk/test/CodeGen/mrtd.c
    cfe/trunk/test/Sema/decl-microsoft-call-conv.c
    cfe/trunk/test/Sema/stdcall-fastcall.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=218166&r1=218165&r2=218166&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Sep 19 18:07:12 2014
@@ -2236,6 +2236,9 @@ def warn_cconv_ignored : Warning<
   "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
 def err_cconv_knr : Error<
   "function with no prototype cannot use %0 calling convention">;
+def warn_cconv_knr : Warning<
+  "function with no prototype cannot use %0 calling convention">,
+  DefaultError, InGroup<DiagGroup<"missing-prototype-for-cc">>;
 def err_cconv_varargs : Error<
   "variadic function cannot use %0 calling convention">;
 def warn_cconv_varargs : Warning<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=218166&r1=218165&r2=218166&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Sep 19 18:07:12 2014
@@ -7937,15 +7937,19 @@ bool Sema::CheckFunctionDeclaration(Scop
 
   // Semantic checking for this function declaration (in isolation).
 
-  // Diagnose the use of X86 fastcall on unprototyped functions.
+  // Diagnose the use of callee-cleanup calls on unprototyped functions.
   QualType NewQType = Context.getCanonicalType(NewFD->getType());
   const FunctionType *NewType = cast<FunctionType>(NewQType);
   if (isa<FunctionNoProtoType>(NewType)) {
     FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo();
-    if (NewTypeInfo.getCC() == CC_X86FastCall)
-      Diag(NewFD->getLocation(), diag::err_cconv_knr)
-          << FunctionType::getNameForCallConv(CC_X86FastCall);
-    // TODO: Also diagnose unprototyped stdcall functions?
+    if (isCalleeCleanup(NewTypeInfo.getCC())) {
+      // Windows system headers sometimes accidentally use stdcall without
+      // (void) parameters, so use a default-error warning in this case :-/
+      int DiagID = NewTypeInfo.getCC() == CC_X86StdCall
+          ? diag::warn_cconv_knr : diag::err_cconv_knr;
+      Diag(NewFD->getLocation(), DiagID)
+          << FunctionType::getNameForCallConv(NewTypeInfo.getCC());
+    }
   }
 
   if (getLangOpts().CPlusPlus) {

Modified: cfe/trunk/test/CodeGen/mangle-windows.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mangle-windows.c?rev=218166&r1=218165&r2=218166&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/mangle-windows.c (original)
+++ cfe/trunk/test/CodeGen/mangle-windows.c Fri Sep 19 18:07:12 2014
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-mingw32 | FileCheck %s
 
+// prototype-less __stdcall functions are only allowed in system headers.
+# 1 "fake_system_header.h" 1 3 4
+
 void __stdcall f1(void) {}
 // CHECK: define x86_stdcallcc void @"\01_f1 at 0"
 

Modified: cfe/trunk/test/CodeGen/mrtd.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mrtd.c?rev=218166&r1=218165&r2=218166&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/mrtd.c (original)
+++ cfe/trunk/test/CodeGen/mrtd.c Fri Sep 19 18:07:12 2014
@@ -1,4 +1,9 @@
-// RUN: %clang_cc1 -mrtd -triple i386-unknown-unknown -std=c89 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -mrtd -triple i386-unknown-unknown -std=c89 -Wsystem-headers  -Wno-error=missing-prototype-for-cc -emit-llvm -o - %s 2>&1 | FileCheck %s
+
+// prototype-less __stdcall functions are only allowed in system headers.
+# 1 "fake_system_header.h" 1 3 4
+
+// CHECK: fake_system_header.h:9:3: warning: function with no prototype cannot use stdcall calling convention
 
 void baz(int arg);
 

Modified: cfe/trunk/test/Sema/decl-microsoft-call-conv.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/decl-microsoft-call-conv.c?rev=218166&r1=218165&r2=218166&view=diff
==============================================================================
--- cfe/trunk/test/Sema/decl-microsoft-call-conv.c (original)
+++ cfe/trunk/test/Sema/decl-microsoft-call-conv.c Fri Sep 19 18:07:12 2014
@@ -2,8 +2,28 @@
 
 // It's important that this is a .c file.
 
-// This is fine, as CrcGenerateTable() has a prototype.
-void __fastcall CrcGenerateTable(void);
-void __fastcall CrcGenerateTable() {}
+// This is fine, as CrcGenerateTable*() has a prototype.
+void __fastcall CrcGenerateTableFastcall(void);
+void __fastcall CrcGenerateTableFastcall() {}
+void __stdcall CrcGenerateTableStdcall(void);
+void __stdcall CrcGenerateTableStdcall() {}
+void __thiscall CrcGenerateTableThiscall(void);
+void __thiscall CrcGenerateTableThiscall() {}
+void __pascal CrcGenerateTablePascal(void);
+void __pascal CrcGenerateTablePascal() {}
 
-void __fastcall CrcGenerateTableNoProto() {} // expected-error{{function with no prototype cannot use fastcall calling convention}}
+void __fastcall CrcGenerateTableNoProtoFastcall() {} // expected-error{{function with no prototype cannot use fastcall calling convention}}
+void __stdcall CrcGenerateTableNoProtoStdcall() {} // expected-error{{function with no prototype cannot use stdcall calling convention}}
+void __thiscall CrcGenerateTableNoProtoThiscall() {} // expected-error{{function with no prototype cannot use thiscall calling convention}}
+void __pascal CrcGenerateTableNoProtoPascal() {} // expected-error{{function with no prototype cannot use pascal calling convention}}
+
+// Regular calling convention is fine.
+void CrcGenerateTableNoProto() {}
+
+
+// In system headers, the stdcall version should be a warning.
+# 1 "fake_system_header.h" 1 3 4
+void __fastcall SystemHeaderFastcall() {} // expected-error{{function with no prototype cannot use fastcall calling convention}}
+void __stdcall SystemHeaderStdcall() {}
+void __thiscall SystemHeaderThiscall() {} // expected-error{{function with no prototype cannot use thiscall calling convention}}
+void __pascal SystemHeaderPascal() {} // expected-error{{function with no prototype cannot use pascal calling convention}}

Modified: cfe/trunk/test/Sema/stdcall-fastcall.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/stdcall-fastcall.c?rev=218166&r1=218165&r2=218166&view=diff
==============================================================================
--- cfe/trunk/test/Sema/stdcall-fastcall.c (original)
+++ cfe/trunk/test/Sema/stdcall-fastcall.c Fri Sep 19 18:07:12 2014
@@ -6,7 +6,7 @@ int __attribute__((fastcall)) var2; // e
 
 // Different CC qualifiers are not compatible
 void __attribute__((stdcall, fastcall)) foo3(void); // expected-error{{fastcall and stdcall attributes are not compatible}}
-void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}}
+void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}} expected-error{{function with no prototype cannot use stdcall calling convention}}
 void __attribute__((fastcall)) foo4(void); // expected-error{{function declared 'fastcall' here was previously declared 'stdcall'}}
 
 // rdar://8876096





More information about the cfe-commits mailing list