r212171 - Don't accept qualified 'int' main return types in C++ or standard C mode
Richard Smith
richard at metafoo.co.uk
Wed Jul 2 16:54:18 PDT 2014
On Wed, Jul 2, 2014 at 3:32 PM, Matt Calabrese <rivorus at gmail.com> wrote:
> I'm probably mis-remembering, but I could have sworn that for built-in
> types, cv-qualification was always ignored in the return type such that
> "int foo()" and "int const foo()" were the same, with cv-qualification only
> mattering for class types.
>
That's not quite what happens. A prvalue expression of non-class, non-array
type has its cv-qualifiers discarded before anything else happens.
Given
const int f();
the expression 'f();' has type 'int' (because the 'const' is discarded), but
int f();
is ill-formed.
On Wed, Jul 2, 2014 at 12:07 AM, Alp Toker <alp at nuanti.com> wrote:
>
>> Author: alp
>> Date: Wed Jul 2 02:07:20 2014
>> New Revision: 212171
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=212171&view=rev
>> Log:
>> 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.
>>
>> Modified:
>> cfe/trunk/lib/Sema/SemaDecl.cpp
>> cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp
>> cfe/trunk/test/Sema/c89.c
>>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=212171&r1=212170&r2=212171&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jul 2 02:07:20 2014
>> @@ -7878,32 +7878,37 @@ void Sema::CheckMain(FunctionDecl* FD, c
>> 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);
>>
>
Should we also produce an ExtWarn here if the type is not 'int'?
+ 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);
>>
>
Can we fold the two halves of this 'if' together? They look very similar...
> + }
>> }
>>
>> // Treat protoless main() as nullary.
>>
>> Modified: cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp?rev=212171&r1=212170&r2=212171&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp
>> (original)
>> +++ cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp Wed Jul
>> 2 02:07:20 2014
>> @@ -62,6 +62,8 @@ main( // expected-error {{first paramete
>> ) {
>> }
>>
>> +const int main(); // expected-error {{'main' must return 'int'}}
>> +
>> #elif TEST7
>>
>> // expected-no-diagnostics
>>
>> Modified: cfe/trunk/test/Sema/c89.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/c89.c?rev=212171&r1=212170&r2=212171&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Sema/c89.c (original)
>> +++ cfe/trunk/test/Sema/c89.c Wed Jul 2 02:07:20 2014
>> @@ -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}} */
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
>
> --
> -Matt Calabrese
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140702/4ae3733b/attachment.html>
More information about the cfe-commits
mailing list