Skip to content

Commit b63b6ee

Browse files
committed
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
1 parent 407e442 commit b63b6ee

File tree

4 files changed

+19
-3
lines changed

4 files changed

+19
-3
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ def ext_noreturn_main : ExtWarn<
425425
def note_main_remove_noreturn : Note<"remove '_Noreturn'">;
426426
def err_constexpr_main : Error<
427427
"'main' is not allowed to be declared constexpr">;
428+
def err_deleted_main : Error<"'main' is not allowed to be deleted">;
428429
def err_mainlike_template_decl : Error<"%0 cannot be a template">;
429430
def err_main_returns_nonint : Error<"'main' must return 'int'">;
430431
def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
@@ -437,6 +438,8 @@ def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
437438
def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
438439
"parameter of 'main' (%select{argument count|argument array|environment|"
439440
"platform-specific data}0) must be of type %1">;
441+
def ext_main_used : Extension<
442+
"ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>;
440443

441444
/// parser diagnostics
442445
def ext_no_declarators : ExtWarn<"declaration does not declare anything">,

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6809,6 +6809,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
68096809
}
68106810

68116811
// If a function is defined as defaulted or deleted, mark it as such now.
6812+
// FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function
6813+
// definition kind to FDK_Definition.
68126814
switch (D.getFunctionDefinitionKind()) {
68136815
case FDK_Declaration:
68146816
case FDK_Definition:
@@ -7670,8 +7672,9 @@ static SourceRange getResultSourceRange(const FunctionDecl *FD) {
76707672
}
76717673

76727674
void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
7673-
// C++11 [basic.start.main]p3: A program that declares main to be inline,
7674-
// static or constexpr is ill-formed.
7675+
// C++11 [basic.start.main]p3:
7676+
// A program that [...] declares main to be inline, static or
7677+
// constexpr is ill-formed.
76757678
// C11 6.7.4p4: In a hosted environment, no function specifier(s) shall
76767679
// appear in a declaration of main.
76777680
// static main is not an error under C99, but we should warn about it.

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11984,6 +11984,11 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
1198411984
}
1198511985
}
1198611986

11987+
// C++11 [basic.start.main]p3:
11988+
// A program that defines main as deleted [...] is ill-formed.
11989+
if (Fn->isMain())
11990+
Diag(DelLoc, diag::err_deleted_main);
11991+
1198711992
Fn->setDeletedAsWritten();
1198811993
}
1198911994

clang/lib/Sema/SemaExpr.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,18 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
264264
SmallVectorImpl<PartialDiagnosticAt> &Suppressed = Pos->second;
265265
for (unsigned I = 0, N = Suppressed.size(); I != N; ++I)
266266
Diag(Suppressed[I].first, Suppressed[I].second);
267-
267+
268268
// Clear out the list of suppressed diagnostics, so that we don't emit
269269
// them again for this specialization. However, we don't obsolete this
270270
// entry from the table, because we want to avoid ever emitting these
271271
// diagnostics again.
272272
Suppressed.clear();
273273
}
274+
275+
// C++ [basic.start.main]p3:
276+
// The function 'main' shall not be used within a program.
277+
if (cast<FunctionDecl>(D)->isMain())
278+
Diag(Loc, diag::ext_main_used);
274279
}
275280

276281
// See if this is an auto-typed variable whose initializer we are parsing.

0 commit comments

Comments
 (0)