jansvoboda11 created this revision. jansvoboda11 added reviewers: Bigcheese, dexonsmith. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This patch correctly reports success/failure of `ParseLangArgs`. Besides being consistent with other `Parse` functions, this is requires to make round-tripping of `LangOptions` work. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D95792 Files: clang/include/clang/Frontend/CompilerInvocation.h clang/lib/Frontend/CompilerInvocation.cpp
Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2632,10 +2632,11 @@ GenerateArg(Args, OPT_fdeclare_opencl_builtins, SA); } -void CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, +bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, const llvm::Triple &T, std::vector<std::string> &Includes, DiagnosticsEngine &Diags) { + bool Success = true; // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; if (const Arg *A = Args.getLastArg(OPT_std_EQ)) { @@ -2643,6 +2644,7 @@ if (LangStd == LangStandard::lang_unspecified) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); + Success = false; // Report supported standards with short description. for (unsigned KindValue = 0; KindValue != LangStandard::lang_unspecified; @@ -2673,6 +2675,7 @@ if (!IsInputCompatibleWithStandard(IK, Std)) { Diags.Report(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) << GetInputKindName(IK); + Success = false; } } } @@ -2694,6 +2697,7 @@ if (OpenCLLangStd == LangStandard::lang_unspecified) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); + Success = false; } else LangStd = OpenCLLangStd; @@ -2708,7 +2712,6 @@ // The key paths of codegen options defined in Options.td start with // "LangOpts->". Let's provide the expected variable name and type. LangOptions *LangOpts = &Opts; - bool Success = true; #define LANG_OPTION_WITH_MARSHALLING( \ PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ @@ -2732,8 +2735,10 @@ if (Opts.ObjC) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { StringRef value = arg->getValue(); - if (Opts.ObjCRuntime.tryParse(value)) + if (Opts.ObjCRuntime.tryParse(value)) { Diags.Report(diag::err_drv_unknown_objc_runtime) << value; + Success = false; + } } if (Args.hasArg(OPT_fobjc_gc_only)) @@ -2742,8 +2747,10 @@ Opts.setGC(LangOptions::HybridGC); else if (Args.hasArg(OPT_fobjc_arc)) { Opts.ObjCAutoRefCount = 1; - if (!Opts.ObjCRuntime.allowsARC()) + if (!Opts.ObjCRuntime.allowsARC()) { Diags.Report(diag::err_arc_unsupported_on_runtime); + Success = false; + } } // ObjCWeakRuntime tracks whether the runtime supports __weak, not @@ -2762,8 +2769,10 @@ assert(!Opts.ObjCWeak); } else if (Opts.getGC() != LangOptions::NonGC) { Diags.Report(diag::err_objc_weak_with_gc); + Success = false; } else if (!Opts.ObjCWeakRuntime) { Diags.Report(diag::err_objc_weak_unsupported); + Success = false; } else { Opts.ObjCWeak = 1; } @@ -2787,6 +2796,7 @@ if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); + Success = false; } Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch; } @@ -2803,9 +2813,11 @@ Opts.MSCompatibilityVersion = 0; if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) { VersionTuple VT; - if (VT.tryParse(A->getValue())) + if (VT.tryParse(A->getValue())) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); + Success = false; + } Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 + VT.getMinor().getValueOr(0) * 100000 + VT.getSubminor().getValueOr(0); @@ -2839,13 +2851,17 @@ // -mrtd option if (Arg *A = Args.getLastArg(OPT_mrtd)) { - if (Opts.getDefaultCallingConv() != LangOptions::DCC_None) + if (Opts.getDefaultCallingConv() != LangOptions::DCC_None) { Diags.Report(diag::err_drv_argument_not_allowed_with) << A->getSpelling() << "-fdefault-calling-conv"; + Success = false; + } else { - if (T.getArch() != llvm::Triple::x86) + if (T.getArch() != llvm::Triple::x86) { Diags.Report(diag::err_drv_argument_not_allowed_with) << A->getSpelling() << T.getTriple(); + Success = false; + } else Opts.setDefaultCallingConv(LangOptions::DCC_StdCall); } @@ -2880,6 +2896,7 @@ case llvm::Triple::nvptx: case llvm::Triple::nvptx64: Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str(); + Success = false; break; } } @@ -2925,11 +2942,15 @@ TT.getArch() == llvm::Triple::nvptx64 || TT.getArch() == llvm::Triple::amdgcn || TT.getArch() == llvm::Triple::x86 || - TT.getArch() == llvm::Triple::x86_64)) + TT.getArch() == llvm::Triple::x86_64)) { Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i); - else if (getArchPtrSize(T) != getArchPtrSize(TT)) + Success = false; + } + else if (getArchPtrSize(T) != getArchPtrSize(TT)) { Diags.Report(diag::err_drv_incompatible_omp_arch) << A->getValue(i) << T.str(); + Success = false; + } else Opts.OMPTargetTriples.push_back(TT); } @@ -2985,8 +3006,10 @@ Opts.setDefaultFPContractMode(LangOptions::FPM_Off); else if (Val == "fast-honor-pragmas") Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas); - else + else { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; + Success = false; + } } // Parse -fsanitize= arguments. @@ -3030,6 +3053,7 @@ } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); + Success = false; } } @@ -3045,9 +3069,11 @@ else if (SignScope.equals_lower("non-leaf")) Opts.setSignReturnAddressScope( LangOptions::SignReturnAddressScopeKind::NonLeaf); - else + else { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << SignScope; + Success = false; + } if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { StringRef SignKey = A->getValue(); @@ -3058,12 +3084,16 @@ else if (SignKey.equals_lower("b_key")) Opts.setSignReturnAddressKey( LangOptions::SignReturnAddressKeyKind::BKey); - else + else { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << SignKey; + Success = false; + } } } } + + return Success; } static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { @@ -3404,8 +3434,8 @@ } else { // Other LangOpts are only initialized when the input is not AST or LLVM IR. // FIXME: Should we really be calling this for an Language::Asm input? - ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes, - Diags); + Success &= ParseLangArgs(LangOpts, Args, DashX, T, + Res.getPreprocessorOpts().Includes, Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) LangOpts.ObjCExceptions = 1; if (T.isOSDarwin() && DashX.isPreprocessed()) { Index: clang/include/clang/Frontend/CompilerInvocation.h =================================================================== --- clang/include/clang/Frontend/CompilerInvocation.h +++ clang/include/clang/Frontend/CompilerInvocation.h @@ -249,7 +249,7 @@ DiagnosticsEngine &Diags); /// Parse command line options that map to LangOptions. - static void ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args, + static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args, InputKind IK, const llvm::Triple &T, std::vector<std::string> &Includes, DiagnosticsEngine &Diags);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits