summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-07-06 02:13:46 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-07-06 02:13:46 +0000
commit027f9c4026a8da9eb2714ae381f1966459dc9839 (patch)
tree741d8b308c982d76f4c423b2b202636949a9aa0d
parent574d521c85ed1fd00f751bf45cf0648db25dc088 (diff)
downloadbcm5719-llvm-027f9c4026a8da9eb2714ae381f1966459dc9839.tar.gz
bcm5719-llvm-027f9c4026a8da9eb2714ae381f1966459dc9839.zip
Sema: Fix a crash when main is redeclared as a function-template.
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. llvm-svn: 185745
-rw-r--r--clang/lib/Sema/SemaDecl.cpp16
-rw-r--r--clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp9
2 files changed, 17 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d20023d13a5..2024acc9755 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -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() ||
diff --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
index a5386f1b925..cd912b834d7 100644
--- a/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
+++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
@@ -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
OpenPOWER on IntegriCloud