Enforce restrictions that 'main' is not allowed to be deleted, or to be used by
the program, in C++. (We allow the latter as an extension, since we've always
permitted it, and GCC does the same, and our supported C++ ABIs don't do
anything special in main.)
llvm-svn: 199782
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c08d87d..9dac4d5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6809,6 +6809,8 @@
}
// If a function is defined as defaulted or deleted, mark it as such now.
+ // FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function
+ // definition kind to FDK_Definition.
switch (D.getFunctionDefinitionKind()) {
case FDK_Declaration:
case FDK_Definition:
@@ -7670,8 +7672,9 @@
}
void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
- // C++11 [basic.start.main]p3: A program that declares main to be inline,
- // static or constexpr is ill-formed.
+ // C++11 [basic.start.main]p3:
+ // A program that [...] declares main to be inline, static or
+ // constexpr is ill-formed.
// C11 6.7.4p4: In a hosted environment, no function specifier(s) shall
// appear in a declaration of main.
// static main is not an error under C99, but we should warn about it.
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 39d71e2..76b9d66 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11984,6 +11984,11 @@
}
}
+ // C++11 [basic.start.main]p3:
+ // A program that defines main as deleted [...] is ill-formed.
+ if (Fn->isMain())
+ Diag(DelLoc, diag::err_deleted_main);
+
Fn->setDeletedAsWritten();
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3640c5ad..ff54b6b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -264,13 +264,18 @@
SmallVectorImpl<PartialDiagnosticAt> &Suppressed = Pos->second;
for (unsigned I = 0, N = Suppressed.size(); I != N; ++I)
Diag(Suppressed[I].first, Suppressed[I].second);
-
+
// Clear out the list of suppressed diagnostics, so that we don't emit
// them again for this specialization. However, we don't obsolete this
// entry from the table, because we want to avoid ever emitting these
// diagnostics again.
Suppressed.clear();
}
+
+ // C++ [basic.start.main]p3:
+ // The function 'main' shall not be used within a program.
+ if (cast<FunctionDecl>(D)->isMain())
+ Diag(Loc, diag::ext_main_used);
}
// See if this is an auto-typed variable whose initializer we are parsing.