]> granicus.if.org Git - clang/commitdiff
Sema: Fix a crash when main is redeclared as a function-template.
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 6 Jul 2013 02:13:46 +0000 (02:13 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 6 Jul 2013 02:13:46 +0000 (02:13 +0000)
This boils down to us sending invalid function decls to
CheckFunctionDeclaration becauswe we did not consider that CheckMain
could cause the decl to be invalid.  Instead, interogate the new decl's
main-validity and *then* send it over to get CheckFunctionDeclaration'd
if it was still valid after calling CheckMain.

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

lib/Sema/SemaDecl.cpp
test/CXX/basic/basic.start/basic.start.main/p2.cpp

index d20023d13a5d5607124d6b092945b012da3c5940..2024acc97558b28e7f59087cdb3953ab2f2ec280 100644 (file)
@@ -6473,12 +6473,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
   if (!getLangOpts().CPlusPlus) {
     // Perform semantic checking on the function declaration.
     bool isExplicitSpecialization=false;
-    if (!NewFD->isInvalidDecl()) {
-      if (NewFD->isMain())
-        CheckMain(NewFD, D.getDeclSpec());
+    if (!NewFD->isInvalidDecl() && NewFD->isMain())
+      CheckMain(NewFD, D.getDeclSpec());
+
+    if (!NewFD->isInvalidDecl())
       D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
                                                   isExplicitSpecialization));
-    }
     // Make graceful recovery from an invalid redeclaration.
     else if (!Previous.empty())
            D.setRedeclaration(true);
@@ -6590,17 +6590,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
 
     // Perform semantic checking on the function declaration.
     if (!isDependentClassScopeExplicitSpecialization) {
+      if (!NewFD->isInvalidDecl() && NewFD->isMain())
+        CheckMain(NewFD, D.getDeclSpec());
+
       if (NewFD->isInvalidDecl()) {
         // If this is a class member, mark the class invalid immediately.
         // This avoids some consistency errors later.
         if (CXXMethodDecl* methodDecl = dyn_cast<CXXMethodDecl>(NewFD))
           methodDecl->getParent()->setInvalidDecl();
-      } else {
-        if (NewFD->isMain()) 
-          CheckMain(NewFD, D.getDeclSpec());
+      } else
         D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
                                                     isExplicitSpecialization));
-      }
     }
 
     assert((NewFD->isInvalidDecl() || !D.isRedeclaration() ||
index a5386f1b92575e6cb852bb50d5e98520683cd701..cd912b834d7b932d655e53307d4f0becd55163e1 100644 (file)
@@ -15,6 +15,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST10
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST11
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST12
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST12
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST13
 
 #if TEST1
 
@@ -94,6 +96,13 @@ int main(int, charT* const *) {}
 typedef char charT;
 int main(int, const charT* const *) {}
 
+#elif TEST13
+
+int main(void) {}
+
+template <typename T>
+int main(void); // expected-error{{'main' cannot be a template}}
+
 #else
 
 #error Unknown test mode