]> granicus.if.org Git - clang/commitdiff
Move the no-prototype calling conv check after decl merging
authorReid Kleckner <reid@kleckner.net>
Mon, 3 Nov 2014 21:56:03 +0000 (21:56 +0000)
committerReid Kleckner <reid@kleckner.net>
Mon, 3 Nov 2014 21:56:03 +0000 (21:56 +0000)
Now we don't warn on this code:
  void __stdcall f(void);
  void __stdcall f();

My previous commit regressed this functionality because I didn't update
the relevant test case which used a definition.

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

lib/Sema/SemaDecl.cpp
test/Sema/decl-microsoft-call-conv.c

index b9f8f637e21d96112cc61ff8bbf2d2935fbee6be..109c01c889267699fc9a00d1f2a5124056c05b47 100644 (file)
@@ -7383,10 +7383,21 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     if (!NewFD->isInvalidDecl() && NewFD->isMSVCRTEntryPoint())
       CheckMSVCRTEntryPoint(NewFD);
 
+    if (!NewFD->isInvalidDecl())
+      D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
+                                                  isExplicitSpecialization));
+    else if (!Previous.empty())
+      // Make graceful recovery from an invalid redeclaration.
+      D.setRedeclaration(true);
+    assert((NewFD->isInvalidDecl() || !D.isRedeclaration() ||
+            Previous.getResultKind() != LookupResult::FoundOverloaded) &&
+           "previous declaration set still overloaded");
+
     // Diagnose no-prototype function declarations with calling conventions that
-    // don't support variadic calls.
-    const FunctionType *FT = R->castAs<FunctionType>();
-    if (FT->isFunctionNoProtoType() && !D.isFunctionDefinition()) {
+    // don't support variadic calls. Only do this in C and do it after merging
+    // possibly prototyped redeclarations.
+    const FunctionType *FT = NewFD->getType()->castAs<FunctionType>();
+    if (isa<FunctionNoProtoType>(FT) && !D.isFunctionDefinition()) {
       CallingConv CC = FT->getExtInfo().getCC();
       if (!supportsVariadicCall(CC)) {
         // Windows system headers sometimes accidentally use stdcall without
@@ -7397,16 +7408,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
             << FunctionType::getNameForCallConv(CC);
       }
     }
-
-    if (!NewFD->isInvalidDecl())
-      D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
-                                                  isExplicitSpecialization));
-    else if (!Previous.empty())
-      // Make graceful recovery from an invalid redeclaration.
-      D.setRedeclaration(true);
-    assert((NewFD->isInvalidDecl() || !D.isRedeclaration() ||
-            Previous.getResultKind() != LookupResult::FoundOverloaded) &&
-           "previous declaration set still overloaded");
   } else {
     // C++11 [replacement.functions]p3:
     //  The program's definitions shall not be specified as inline.
index cefaf4f40b0e9a9566a5004b870230d6c4d8ccc9..5a83b38b192f5127d2942869d911327c4815fbed 100644 (file)
@@ -4,14 +4,19 @@
 
 // This is fine, as CrcGenerateTable*() has a prototype.
 void __fastcall CrcGenerateTableFastcall(void);
+void __fastcall CrcGenerateTableFastcall();
 void __fastcall CrcGenerateTableFastcall() {}
 void __stdcall CrcGenerateTableStdcall(void);
+void __stdcall CrcGenerateTableStdcall();
 void __stdcall CrcGenerateTableStdcall() {}
 void __thiscall CrcGenerateTableThiscall(void);
+void __thiscall CrcGenerateTableThiscall();
 void __thiscall CrcGenerateTableThiscall() {}
 void __pascal CrcGenerateTablePascal(void);
+void __pascal CrcGenerateTablePascal();
 void __pascal CrcGenerateTablePascal() {}
 void __vectorcall CrcGenerateTableVectorcall(void);
+void __vectorcall CrcGenerateTableVectorcall();
 void __vectorcall CrcGenerateTableVectorcall() {}
 
 void __fastcall CrcGenerateTableNoProtoFastcall(); // expected-error{{function with no prototype cannot use the fastcall calling convention}}