08.02.2012 23:47, David Blaikie пишет:
On Wed, Feb 8, 2012 at 11:25 AM, Chris Lattner<[email protected]> wrote:
On Feb 8, 2012, at 5:31 AM, Vasiliy Korchagin wrote:
07.02.2012 07:27, Eli Friedman пишет:
On Mon, Feb 6, 2012 at 6:51 PM, Xin Tong<[email protected]> wrote:
Is there any way to stop this ?
/home/socrates/llvm/llvm-3.0.src/benchmarks/powerstone/crc/crc.c:67:1:
error: 'main' must return 'int'
void main()
^
1 error generated.
You mean besides fixing the source of your benchmark so it's valid C?
Not at the moment... patches welcome.
-Eli
We suggest patch for allowing main() function to have non-integer return type. This
feature can be enabled with "-allow-non-int-main" option. In this case warning
about incorrect main() return type will be printed instead of error.
In patch also included test case for this feature.
Vasiliy Korchagin,
Hi Vasiliy,
Please send clang patches to cfe-dev.
or even cfe-commits (further instructions are here:
http://clang.llvm.org/get_involved.html)
[I've dropped llvm-dev and added cfe-commits to this email]
My first thought based on your description alone would be that we
should support this, if at all, probably in the way that GCC already
does - surfacing non-int returning main as a warning in C (under
-Wmain) and error in C++ (as it is already) if that's practical.
& looking at the patch itself: Your change is even more permissive
than GCC (when you use the flag you've added) allowing C++ to have
void returning main. I don't see any need to be so accepting.
(& the change you've made in Sema::ActOnFinishFunctionBody scares me a
bit - what does that do when you have int returning main but you turn
this flag on? not allow implicit return 0? that seems problematic)
- David
David, thanks for your reply.
I changed the patch and now "-allow-non-int-main" option allows to print
a warning in C and error in C++ in case of non-integer main. I also
fixed implicit returning 0.
- Vasiliy
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index cbb4d17..3e5ee6c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -348,6 +348,8 @@ def err_constexpr_main : Error<
"'main' is not allowed to be declared constexpr">;
def err_main_template_decl : Error<"'main' cannot be a template">;
def err_main_returns_nonint : Error<"'main' must return 'int'">;
+def warn_main_returns_nonint : Warning<"return type of 'main' is not 'int'">,
+ InGroup<Main>;
def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
"must be 0, 2, or 3">;
def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index d2dff89..f80f720 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -56,6 +56,7 @@ BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
"Objective-C auto-synthesized properties")
BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1,
"Objective-C related result type inference")
+LANGOPT(AllowNonIntMain , 1, 0, "Allow main() to have non-integer return type.")
LANGOPT(Trigraphs , 1, 0,"trigraphs")
LANGOPT(BCPLComment , 1, 0, "BCPL-style '//' comments")
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 557e73b..63887c1 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -478,6 +478,8 @@ def foverride_record_layout_EQ : Joined<"-foverride-record-layout=">,
// Language Options
//===----------------------------------------------------------------------===//
+def allow_non_int_main : Flag<"-allow-non-int-main">,
+ HelpText<"Allow main() to have non-integer return type">;
def fno_builtin : Flag<"-fno-builtin">,
HelpText<"Disable implicit builtin knowledge of functions">;
def faltivec : Flag<"-faltivec">,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index f0c7f05..310fc1d 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -214,6 +214,8 @@ def X_Joined : Joined<"-X">;
def Z_Flag : Flag<"-Z">;
def Z_Joined : Joined<"-Z">;
def all__load : Flag<"-all_load">;
+def allow_non_int_main : Flag<"-allow-non-int-main">,
+ HelpText<"Allow main() to have non-integer return type">;
def allowable__client : Separate<"-allowable_client">;
def ansi : Flag<"-ansi">, Group<a_Group>;
def arch__errors__fatal : Flag<"-arch_errors_fatal">;
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index e59794c..c93981c 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -326,8 +326,15 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
EmitMCountInstrumentation();
if (RetTy->isVoidType()) {
- // Void type; nothing to return.
- ReturnValue = 0;
+ const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
+ if (FD->isMain() && getLangOptions().AllowNonIntMain) {
+ // C and C++ allow for main to automatically return 0. ReturnValue should
+ // not be null pointer to return some value.
+ ReturnValue = CreateIRTemp(RetTy, "retval");
+ } else {
+ // Void type; nothing to return.
+ ReturnValue = 0;
+ }
} else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
hasAggregateLLVMType(CurFnInfo->getReturnType())) {
// Indirect aggregate return; emit returned value directly into sret slot.
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 714a21a..aad4980 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1846,6 +1846,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue(Args));
}
+ if (Args.hasArg(options::OPT_allow_non_int_main))
+ CmdArgs.push_back("-allow-non-int-main");
+
if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
options::OPT_Wlarge_by_value_copy_def)) {
CmdArgs.push_back("-Wlarge-by-value-copy");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 8417aa4..406ac2a 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -653,6 +653,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
// It would be better to push the all target specific choices into the driver,
// so that everything below that was more uniform.
+ if (Opts.AllowNonIntMain)
+ Res.push_back("-allow-non-int-main");
if (Opts.Trigraphs)
Res.push_back("-trigraphs");
// Implicit based on the input kind:
@@ -1746,6 +1748,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
Opts.GNUKeywords);
+ if (Args.hasArg(OPT_allow_non_int_main) && IK == IK_C)
+ Opts.AllowNonIntMain = 1;
+
if (Args.hasArg(OPT_fno_operator_names))
Opts.CXXOperatorNames = 0;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 3d24c59..ca6ebec 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5813,8 +5813,12 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
const FunctionType* FT = T->getAs<FunctionType>();
if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
- Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
- FD->setInvalidDecl(true);
+ if (Context.getLangOptions().AllowNonIntMain) {
+ Diag(FD->getTypeSpecStartLoc(), diag::warn_main_returns_nonint);
+ } else {
+ Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
+ FD->setInvalidDecl(true);
+ }
}
// Treat protoless main() as nullary.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits