summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlp Toker <alp@nuanti.com>2014-07-02 07:07:20 +0000
committerAlp Toker <alp@nuanti.com>2014-07-02 07:07:20 +0000
commit70fc29ca86f0f852ed0e3d007cff7b45bb396e7c (patch)
tree1ac8daef9f9e14a8af87f5862f13a3b97e509c7a
parentf94baeb363a0c012563c19b7e1e281496543380c (diff)
downloadbcm5719-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.cpp49
-rw-r--r--clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp2
-rw-r--r--clang/test/Sema/c89.c2
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}} */
OpenPOWER on IntegriCloud