]> granicus.if.org Git - clang/commitdiff
Follow-up to r214408: Warn on other callee-cleanup functions without prototype too.
authorNico Weber <nicolasweber@gmx.de>
Fri, 19 Sep 2014 23:07:12 +0000 (23:07 +0000)
committerNico Weber <nicolasweber@gmx.de>
Fri, 19 Sep 2014 23:07:12 +0000 (23:07 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218166 91177308-0d34-0410-b5e6-96231b3b80d8

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

index d567cce2d1e51cdd790c3d3897efc57ca54eed28..559bf62fd8c70c296cd1c05573b42e0e4eab803d 100644 (file)
@@ -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<
index 0aaa60c90fe6d5a002c5302ddb7a0422c9ab12a5..535e33a2b6e605a2561876665383c1c12962dd36 100644 (file)
@@ -7937,15 +7937,19 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
 
   // 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) {
index 37d1018283589c6be3f041e7e81ce67042f7e1df..1d97831c47381a7e453daa9b4e1d77431bd572bc 100644 (file)
@@ -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@0"
 
index 8fa7cf02cead92d583b43f667653d5c08fed76d5..79cd490084f7bc0c6346528de3dd34ce3cef3420 100644 (file)
@@ -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);
 
index 88a6d920a0aa6affbbd8283bafafbb216ac15240..3ec4d5ebea00324aafe4f7d6705f5529f0a351a5 100644 (file)
@@ -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}}
index dea1fc5e7af7502e51b70fbfeef7bce04b25a569..90429327a7b279a3d2d6deeccc502beaed032f3f 100644 (file)
@@ -6,7 +6,7 @@ int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies
 
 // 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