Author: davide Date: Fri Aug 14 09:13:29 2015 New Revision: 245051 URL: http://llvm.org/viewvc/llvm-project?rev=245051&view=rev Log: [Sema] main can't be declared as global variable, in C++.
So, we now reject that. We also warn for any external-linkage global variable named main in C, because it results in undefined behavior. PR: 24309 Differential Revision: http://reviews.llvm.org/D11658 Reviewed by: rsmith Added: cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p3.cpp cfe/trunk/test/Sema/warn-extern-main.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDecl.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=245051&r1=245050&r2=245051&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Aug 14 09:13:29 2015 @@ -510,6 +510,10 @@ def warn_main_one_arg : Warning<"only on def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 " "parameter of 'main' (%select{argument count|argument array|environment|" "platform-specific data}0) must be of type %1">; +def err_main_global_variable : + Error<"main cannot be declared as global variable">; +def warn_main_redefined : Warning<"variable named 'main' with external linkage " + "has undefined behavior">, InGroup<Main>; def ext_main_used : Extension< "ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>; Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=245051&r1=245050&r2=245051&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Aug 14 09:13:29 2015 @@ -6111,6 +6111,22 @@ Sema::ActOnVariableDeclarator(Scope *S, } } + // Special handling of variable named 'main'. + if (Name.isIdentifier() && Name.getAsIdentifierInfo()->isStr("main") && + NewVD->getDeclContext()->getRedeclContext()->isTranslationUnit() && + !getLangOpts().Freestanding && !NewVD->getDescribedVarTemplate()) { + + // C++ [basic.start.main]p3 + // A program that declares a variable main at global scope is ill-formed. + if (getLangOpts().CPlusPlus) + Diag(D.getLocStart(), diag::err_main_global_variable); + + // In C, and external-linkage variable named main results in undefined + // behavior. + else if (NewVD->hasExternalFormalLinkage()) + Diag(D.getLocStart(), diag::warn_main_redefined); + } + if (D.isRedeclaration() && !Previous.empty()) { checkDLLAttributeRedeclaration( *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD, Added: cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p3.cpp?rev=245051&view=auto ============================================================================== --- cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p3.cpp (added) +++ cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p3.cpp Fri Aug 14 09:13:29 2015 @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST1 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST2 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST3 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST4 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -DTEST5 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -DTEST6 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST7 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST8 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST9 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST10 -ffreestanding + +#if TEST1 +int main; // expected-error{{main cannot be declared as global variable}} + +#elif TEST2 +// expected-no-diagnostics +int f () { + int main; + return main; +} + +#elif TEST3 +// expected-no-diagnostics +void x(int main) {}; +int y(int main); + +#elif TEST4 +// expected-no-diagnostics +class A { + static int main; +}; + +#elif TEST5 +// expected-no-diagnostics +template<class T> constexpr T main; + +#elif TEST6 +extern template<class T> constexpr T main; //expected-error{{expected unqualified-id}} + +#elif TEST7 +// expected-no-diagnostics +namespace foo { + int main; +} + +#elif TEST8 +void z(void) +{ + extern int main; // expected-error{{main cannot be declared as global variable}} +} + +#elif TEST9 +// expected-no-diagnostics +int q(void) +{ + static int main; + return main; +} + +#elif TEST10 +// expected-no-diagnostics +int main; + +#else +#error Unknown Test +#endif Added: cfe/trunk/test/Sema/warn-extern-main.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-extern-main.c?rev=245051&view=auto ============================================================================== --- cfe/trunk/test/Sema/warn-extern-main.c (added) +++ cfe/trunk/test/Sema/warn-extern-main.c Fri Aug 14 09:13:29 2015 @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST1 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST2 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST3 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST4 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST5 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST6 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST7 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST8 +// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST9 -ffreestanding + +#if TEST1 +int main; // expected-warning{{variable named 'main' with external linkage has undefined behavior}} + +#elif TEST2 +extern int main; // expected-warning{{variable named 'main' with external linkage has undefined behavior}} + +#elif TEST3 +// expected-no-diagnostics +void x() { + static int main; +} + +#elif TEST4 +void x() { + extern int main; // expected-warning{{variable named 'main' with external linkage has undefined behavior}} +} + +#elif TEST5 +// expected-no-diagnostics +void x() { + int main; +} + +#elif TEST6 +// expected-no-diagnostics +static int main; + +#elif TEST7 +// expected-no-diagnostics +void x() { + auto int main; +} + +#elif TEST8 +// expected-no-diagnostics +void x() { + register int main; +} + +#elif TEST9 +// expected-no-diagnostics +int main; + +#else +#error Unknown Test +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits