summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-07-31 17:19:18 +0000
committerNico Weber <nicolasweber@gmx.de>2014-07-31 17:19:18 +0000
commitbe39a87e1126c229ed69985881d8fb8fc53ce4ff (patch)
tree50992ba6b12c1647df925bdff22bf2c24a34776d
parent8ed8dbd96a8de3da0213f7863de7ba3e588277f9 (diff)
downloadbcm5719-llvm-be39a87e1126c229ed69985881d8fb8fc53ce4ff.tar.gz
bcm5719-llvm-be39a87e1126c229ed69985881d8fb8fc53ce4ff.zip
Delay check for prototype on __fastcall functions until after MergeFunctionDecl.
In C, it is only known after merging decls if a function with 0 arguments has a prototype. Fixes PR20386, see that for more notes. llvm-svn: 214408
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
-rw-r--r--clang/lib/Sema/SemaType.cpp23
-rw-r--r--clang/test/Sema/decl-microsoft-call-conv.c9
3 files changed, 27 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9ce09288de1..4abbbebf808 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7821,6 +7821,18 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
// Semantic checking for this function declaration (in isolation).
+
+ // Diagnose the use of X86 fastcall 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 (getLangOpts().CPlusPlus) {
// C++-specific checks.
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD)) {
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 4ad066a7a7a..47df3a69aab 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -4564,23 +4564,12 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
}
}
- // Diagnose the use of X86 fastcall on unprototyped functions.
- if (CC == CC_X86FastCall) {
- if (isa<FunctionNoProtoType>(fn)) {
- S.Diag(attr.getLoc(), diag::err_cconv_knr)
- << FunctionType::getNameForCallConv(CC);
- attr.setInvalid();
- return true;
- }
-
- // Also diagnose fastcall with regparm.
- if (fn->getHasRegParm()) {
- S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
- << "regparm"
- << FunctionType::getNameForCallConv(CC);
- attr.setInvalid();
- return true;
- }
+ // Also diagnose fastcall with regparm.
+ if (CC == CC_X86FastCall && fn->getHasRegParm()) {
+ S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible)
+ << "regparm" << FunctionType::getNameForCallConv(CC_X86FastCall);
+ attr.setInvalid();
+ return true;
}
// Modify the CC from the wrapped function type, wrap it all back, and then
diff --git a/clang/test/Sema/decl-microsoft-call-conv.c b/clang/test/Sema/decl-microsoft-call-conv.c
new file mode 100644
index 00000000000..88a6d920a0a
--- /dev/null
+++ b/clang/test/Sema/decl-microsoft-call-conv.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -verify %s
+
+// It's important that this is a .c file.
+
+// This is fine, as CrcGenerateTable() has a prototype.
+void __fastcall CrcGenerateTable(void);
+void __fastcall CrcGenerateTable() {}
+
+void __fastcall CrcGenerateTableNoProto() {} // expected-error{{function with no prototype cannot use fastcall calling convention}}
OpenPOWER on IntegriCloud