mirror of
https://github.com/intel/llvm.git
synced 2026-02-02 02:00:03 +08:00
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
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}} */
|
||||
|
||||
Reference in New Issue
Block a user