diff options
author | Alp Toker <alp@nuanti.com> | 2014-07-02 07:07:20 +0000 |
---|---|---|
committer | Alp Toker <alp@nuanti.com> | 2014-07-02 07:07:20 +0000 |
commit | 70fc29ca86f0f852ed0e3d007cff7b45bb396e7c (patch) | |
tree | 1ac8daef9f9e14a8af87f5862f13a3b97e509c7a | |
parent | f94baeb363a0c012563c19b7e1e281496543380c (diff) | |
download | bcm5719-llvm-70fc29ca86f0f852ed0e3d007cff7b45bb396e7c.tar.gz bcm5719-llvm-70fc29ca86f0f852ed0e3d007cff7b45bb396e7c.zip |
Don't accept qualified 'int' main return types in C++ or standard C mode
C++ [basic.start.main]p1: "It shall have a return type of type int"
ISO C is also clear about this, so only accept 'int' with qualifiers in GNUMode
C.
llvm-svn: 212171
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 49 | ||||
-rw-r--r-- | clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp | 2 | ||||
-rw-r--r-- | clang/test/Sema/c89.c | 2 |
3 files changed, 31 insertions, 22 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 849926327d0..791b4daf01e 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7878,32 +7878,37 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { assert(T->isFunctionType() && "function decl is not of function type"); const FunctionType* FT = T->castAs<FunctionType>(); - // All the standards say that main() should should return 'int'. - if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) { + if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { + // In C with GNU extensions we allow main() to have non-integer return + // type, but we should warn about the extension, and we disable the + // implicit-return-zero rule. + + // GCC in C mode accepts qualified 'int'. + if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) + FD->setHasImplicitReturnZero(true); + else { + Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); + SourceRange RTRange = FD->getReturnTypeSourceRange(); + if (RTRange.isValid()) + Diag(RTRange.getBegin(), diag::note_main_change_return_type) + << FixItHint::CreateReplacement(RTRange, "int"); + } + } else { // In C and C++, main magically returns 0 if you fall off the end; // set the flag which tells us that. // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3. - FD->setHasImplicitReturnZero(true); - - // In C with GNU extensions we allow main() to have non-integer return - // type, but we should warn about the extension, and we disable the - // implicit-return-zero rule. - } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { - Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); - SourceRange RTRange = FD->getReturnTypeSourceRange(); - if (RTRange.isValid()) - Diag(RTRange.getBegin(), diag::note_main_change_return_type) - << FixItHint::CreateReplacement(RTRange, "int"); - - // Otherwise, this is just a flat-out error. - } else { - SourceRange RTRange = FD->getReturnTypeSourceRange(); - Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint) - << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int") - : FixItHint()); - - FD->setInvalidDecl(true); + // All the standards say that main() should return 'int'. + if (Context.hasSameType(FT->getReturnType(), Context.IntTy)) + FD->setHasImplicitReturnZero(true); + else { + // Otherwise, this is just a flat-out error. + SourceRange RTRange = FD->getReturnTypeSourceRange(); + Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint) + << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int") + : FixItHint()); + FD->setInvalidDecl(true); + } } // Treat protoless main() as nullary. 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 5c7d60c1df4..42e87e5431f 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 @@ -62,6 +62,8 @@ main( // expected-error {{first parameter of 'main' (argument count) must be of ) { } +const int main(); // expected-error {{'main' must return 'int'}} + #elif TEST7 // expected-no-diagnostics diff --git a/clang/test/Sema/c89.c b/clang/test/Sema/c89.c index b746d383f30..c9e81f1c41c 100644 --- a/clang/test/Sema/c89.c +++ b/clang/test/Sema/c89.c @@ -111,6 +111,8 @@ const array_of_pointer_to_CI mine3; void main() {} /* expected-error {{'main' must return 'int'}} */ +const int main() {} /* expected-error {{'main' must return 'int'}} */ + long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */ -42LL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */ unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */ |