Re: [PATCH] D11658: [Sema] main can't be declared as global variable

2015-08-12 Thread Davide Italiano via cfe-commits
davide updated this revision to Diff 31932.
davide added a comment.

- Refactored check
- Added test for -ffreestanding in C
- Changed the diagnostic emitted

Also, thanks for your time and guidance.


http://reviews.llvm.org/D11658

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/CXX/basic/basic.start/basic.start.main/p3.cpp
  test/Sema/warn-extern-main.c

Index: test/Sema/warn-extern-main.c
===
--- test/Sema/warn-extern-main.c
+++ test/Sema/warn-extern-main.c
@@ -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{{external-linkage variable named 'main' has undefined behavior}}
+
+#elif TEST2
+extern int main; // expected-warning{{external-linkage variable named 'main' has undefined behavior}}
+
+#elif TEST3
+// expected-no-diagnostics
+void x() {
+  static int main;
+}
+
+#elif TEST4
+void x() {
+  extern int main; // expected-warning{{external-linkage variable named 'main' 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
Index: test/CXX/basic/basic.start/basic.start.main/p3.cpp
===
--- test/CXX/basic/basic.start/basic.start.main/p3.cpp
+++ test/CXX/basic/basic.start/basic.start.main/p3.cpp
@@ -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 can't 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
+templateclass T constexpr T main;
+
+#elif TEST6
+extern templateclass 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 can't 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
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6111,6 +6111,22 @@
 }
   }
 
+  // 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_castNamedDecl(Previous.getRepresentativeDecl()), NewVD,
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -510,6 +510,9 @@
 def err_main_arg_wrong : Error%select{first|second|third|fourth}0 
 parameter of 'main' (%select{argument count|argument 

Re: [PATCH] D11658: [Sema] main can't be declared as global variable

2015-08-10 Thread Joerg Sonnenberger via cfe-commits
On Thu, Jul 30, 2015 at 07:01:22PM +, Davide Italiano wrote:
 Index: test/CXX/basic/basic.start/basic.start.main/p3.cpp
 ===
 --- test/CXX/basic/basic.start/basic.start.main/p3.cpp
 +++ test/CXX/basic/basic.start/basic.start.main/p3.cpp
 @@ -0,0 +1,8 @@
 +// RUN: %clang_cc1 -fsyntax-only -verify %s
 +
 +int main; // expected-error{{main can't be declared as global variable}}
 +
 +int f () {
 +  int main; // OK
 +  (void)main;
 +}

What about static int main in file scope?

Joerg
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D11658: [Sema] main can't be declared as global variable

2015-08-10 Thread Richard Smith via cfe-commits
rsmith added a comment.

Maybe you could refactor the check to something like:

  if (Name.isIdentifier()  Name.getAsIdentifierInfo()-isStr(main)
  NewVD-getDeclContext()-getRedeclContext()-isTranslationUnit() 
  !getLangOpts().Freestanding  !NewVD-getDescribedVarTemplate()) {
if (getLangOpts().CPlusPlus)
  Diag1;
else if (NewVD-hasExternalFormalLinkage())
  Diag2;
  }



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:514
@@ +513,3 @@
+def err_main_global_variable : Errormain can't be declared as global 
variable;
+def warn_main_redefined : Warningexternal-linkage variable named 'main' has 
+undefined behavior, InGroupMain;

Hyphenating 'external linkage' is unusual; how about 'variable named 'main' 
with external linkage has undefined behavior'?


Comment at: lib/Sema/SemaDecl.cpp:6113
@@ +6112,3 @@
+// A program that declares a variable main at global scope is ill-formed.
+if (getLangOpts().CPlusPlus  !getLangOpts().Freestanding 
+NewVD-hasGlobalStorage()  !NewVD-isStaticLocal() 

The freestanding check should apply in C too.


Comment at: lib/Sema/SemaDecl.cpp:6114-6116
@@ +6113,5 @@
+if (getLangOpts().CPlusPlus  !getLangOpts().Freestanding 
+NewVD-hasGlobalStorage()  !NewVD-isStaticLocal() 
+!NewVD-isStaticDataMember()  !NewVD-getDescribedVarTemplate() 

+NewVD-getDeclContext()-isTranslationUnit())
+  Diag(D.getLocStart(), diag::err_main_global_variable);

The only checks you need here are: 1) DeclContext's redecl context is the 
translation unit, and 2) NewVD is not a variable template. All the other checks 
are implied by the DC check. I'd suggest factoring these out into the main 
check.


Comment at: lib/Sema/SemaDecl.cpp:6116
@@ +6115,3 @@
+!NewVD-isStaticDataMember()  !NewVD-getDescribedVarTemplate() 

+NewVD-getDeclContext()-isTranslationUnit())
+  Diag(D.getLocStart(), diag::err_main_global_variable);

You need to check `NewVD-getDeclContext()-getRedeclContext()`, in case there 
are `LinkageSpecDecl`s surrounding the variable (`extern C++ int main;`).


Comment at: lib/Sema/SemaDecl.cpp:6121
@@ +6120,3 @@
+// behavior.
+if (!getLangOpts().CPlusPlus  NewVD-isExternC())
+  Diag(D.getLocStart(), diag::warn_main_redefined);

It's weird to ask `isExternC` from C. Use `hasExternalFormalLinkage` instead.


http://reviews.llvm.org/D11658



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits