-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang] add ext warning for missing return in 'main' for C89 mode #134617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) ChangesFixes #21650 Clang currently inserts an implicit Full diff: https://github.com/llvm/llvm-project/pull/134617.diff 5 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5217e04b5e83f..6227b6133da0b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -318,6 +318,7 @@ Improvements to Clang's diagnostics
- ``-Wc++98-compat`` no longer diagnoses use of ``__auto_type`` or
``decltype(auto)`` as though it was the extension for ``auto``. (#GH47900)
+- Clang now issues a warning for missing return in ``main`` in C89 mode. (#GH21650)
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 393bfecf9a36b..34f2ee883ca63 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1031,6 +1031,8 @@ def err_mainlike_template_decl : Error<"%0 cannot be a template">;
def err_main_returns_nonint : Error<"'main' must return 'int'">;
def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
InGroup<MainReturnType>;
+def ext_main_no_return : Extension<"non-void 'main' function does not return a value">,
+ InGroup<MainReturnType>;
def note_main_change_return_type : Note<"change return type to 'int'">;
def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
"must be 0, 2, or 3">;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 3d6da4f70f99e..38aa3f0edf718 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -550,7 +550,8 @@ struct CheckFallThroughDiagnostics {
unsigned FunKind; // TODO: use diag::FalloffFunctionKind
SourceLocation FuncLoc;
- static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
+ static CheckFallThroughDiagnostics MakeForFunction(Sema &S,
+ const Decl *Func) {
CheckFallThroughDiagnostics D;
D.FuncLoc = Func->getLocation();
D.diag_FallThrough_HasNoReturn = diag::warn_noreturn_has_return_expr;
@@ -564,8 +565,13 @@ struct CheckFallThroughDiagnostics {
// Don't suggest that template instantiations be marked "noreturn"
bool isTemplateInstantiation = false;
- if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
+ if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) {
isTemplateInstantiation = Function->isTemplateInstantiation();
+ if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().C99 &&
+ Function->isMain()) {
+ D.diag_FallThrough_ReturnsNonVoid = diag::ext_main_no_return;
+ }
+ }
if (!isVirtualMethod && !isTemplateInstantiation)
D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_function;
@@ -2737,15 +2743,14 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
// Warning: check missing 'return'
if (P.enableCheckFallThrough) {
const CheckFallThroughDiagnostics &CD =
- (isa<BlockDecl>(D)
- ? CheckFallThroughDiagnostics::MakeForBlock()
- : (isa<CXXMethodDecl>(D) &&
- cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
- cast<CXXMethodDecl>(D)->getParent()->isLambda())
- ? CheckFallThroughDiagnostics::MakeForLambda()
- : (fscope->isCoroutine()
- ? CheckFallThroughDiagnostics::MakeForCoroutine(D)
- : CheckFallThroughDiagnostics::MakeForFunction(D)));
+ (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
+ : (isa<CXXMethodDecl>(D) &&
+ cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
+ cast<CXXMethodDecl>(D)->getParent()->isLambda())
+ ? CheckFallThroughDiagnostics::MakeForLambda()
+ : (fscope->isCoroutine()
+ ? CheckFallThroughDiagnostics::MakeForCoroutine(D)
+ : CheckFallThroughDiagnostics::MakeForFunction(S, D)));
CheckFallThroughForBody(S, D, Body, BlockType, CD, AC);
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d630f9bd409fd..b020a1b2fd3e0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16230,7 +16230,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// If the function implicitly returns zero (like 'main') or is naked,
// don't complain about missing return statements.
- if (FD->hasImplicitReturnZero() || FD->hasAttr<NakedAttr>())
+ if ((FD->hasImplicitReturnZero() &&
+ (getLangOpts().CPlusPlus || getLangOpts().C99 || !FD->isMain())) ||
+ FD->hasAttr<NakedAttr>())
WP.disableCheckFallThrough();
// MSVC permits the use of pure specifier (=0) on function definition,
diff --git a/clang/test/Sema/main-no-return-c89.c b/clang/test/Sema/main-no-return-c89.c
new file mode 100644
index 0000000000000..19d55916fc833
--- /dev/null
+++ b/clang/test/Sema/main-no-return-c89.c
@@ -0,0 +1,6 @@
+/* RUN: %clang_cc1 -std=c89 -fsyntax-only -verify -pedantic -Wno-strict-prototypes %s
+ */
+
+int main() {
+
+} /* expected-warning {{non-void 'main' function does not return a value}} */
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for working on this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from an 80-col formatting nit, thank you for the fix!
…vm#134617) Fixes llvm#21650 --- Clang currently inserts an implicit `return 0;` in `main()` when compiling in `C89` mode, even though the `C89` standard doesn't require this behavior. This patch changes that behavior by emitting a warning instead of silently inserting the implicit return under `-pedantic`.
Fixes #21650
Clang currently inserts an implicit
return 0;
inmain()
when compiling inC89
mode, even though theC89
standard doesn't require this behavior. This patch changes that behavior by emitting a warning instead of silently inserting the implicit return under-pedantic
.