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

Reply via email to