hvdijk created this revision.
Herald added subscribers: cfe-commits, atanasyan, arichardson, sdardis.
Herald added a project: clang.
hvdijk requested review of this revision.
clang/lib/CodeGen/BackendUtil.cpp contains multiple checks for attributes of 
LangOpts. The option processing that sets up LangOpts is mostly done by 
ParseLangArgs, which is skipped for LLVM IR files. Because of this, there are 
code generation differences when the -save-temps command line option is used: 
that command line option causes LLVM IR to be emitted to file and a new process 
to be spawned to process that file, which does not process options the same way.

An example of this is

  typedef float __attribute__((ext_vector_type(2))) float2;
  float2 foo (float2 a, float2 b, float2 c) {
    return a * b + c;
  }

This used to generate different code with clang --target=mips -mcpu=mips32r5 
-mfp64 -mmsa -O3 -ffp-contract=fast depending on whether -save-temps was also 
present, because the -ffp-contract=fast option affects instruction selection 
but was ignored for LLVM IR input files.

While CompilerInvocation::CreateFromArgs contained special exceptions for a few 
options that were handled by ParseLangArgs that also need to be handled for 
LLVM IR, there are many more, and just allowing ParseLangArgs to be called 
seems like the simpler fix.

For InputKind::Precompiled, -std=* options were previously silently ignored and 
continue to be silently ignored, as it is reasonable for users to add them and 
in fact this is done in quite a number of tests in the test suite.

For Language::LLVM_IR, -std=* options were previously silently ignored and now 
result in an error, as it is not reasonable for users to add them.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86695

Files:
  clang/lib/Frontend/CompilerInvocation.cpp

Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2432,9 +2432,11 @@
                                           const LangStandard &S) {
   switch (IK.getLanguage()) {
   case Language::Unknown:
-  case Language::LLVM_IR:
     llvm_unreachable("should not parse language flags for this input");
 
+  case Language::LLVM_IR:
+    return false;
+
   case Language::C:
   case Language::ObjC:
   case Language::RenderScript:
@@ -2507,30 +2509,32 @@
     if (LangStd == LangStandard::lang_unspecified) {
       Diags.Report(diag::err_drv_invalid_value)
         << A->getAsString(Args) << A->getValue();
-      // Report supported standards with short description.
-      for (unsigned KindValue = 0;
-           KindValue != LangStandard::lang_unspecified;
-           ++KindValue) {
-        const LangStandard &Std = LangStandard::getLangStandardForKind(
-          static_cast<LangStandard::Kind>(KindValue));
-        if (IsInputCompatibleWithStandard(IK, Std)) {
-          auto Diag = Diags.Report(diag::note_drv_use_standard);
-          Diag << Std.getName() << Std.getDescription();
-          unsigned NumAliases = 0;
+      if (IK.getFormat() != InputKind::Precompiled) {
+        // Report supported standards with short description.
+        for (unsigned KindValue = 0;
+             KindValue != LangStandard::lang_unspecified;
+             ++KindValue) {
+          const LangStandard &Std = LangStandard::getLangStandardForKind(
+            static_cast<LangStandard::Kind>(KindValue));
+          if (IsInputCompatibleWithStandard(IK, Std)) {
+            auto Diag = Diags.Report(diag::note_drv_use_standard);
+            Diag << Std.getName() << Std.getDescription();
+            unsigned NumAliases = 0;
 #define LANGSTANDARD(id, name, lang, desc, features)
 #define LANGSTANDARD_ALIAS(id, alias) \
-          if (KindValue == LangStandard::lang_##id) ++NumAliases;
+            if (KindValue == LangStandard::lang_##id) ++NumAliases;
 #define LANGSTANDARD_ALIAS_DEPR(id, alias)
 #include "clang/Basic/LangStandards.def"
-          Diag << NumAliases;
+            Diag << NumAliases;
 #define LANGSTANDARD(id, name, lang, desc, features)
 #define LANGSTANDARD_ALIAS(id, alias) \
-          if (KindValue == LangStandard::lang_##id) Diag << alias;
+            if (KindValue == LangStandard::lang_##id) Diag << alias;
 #define LANGSTANDARD_ALIAS_DEPR(id, alias)
 #include "clang/Basic/LangStandards.def"
+          }
         }
       }
-    } else {
+    } else if (IK.getFormat() != InputKind::Precompiled) {
       // Valid standard, check to make sure language and standard are
       // compatible.
       const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
@@ -2592,7 +2596,9 @@
   Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
 
   llvm::Triple T(TargetOpts.Triple);
-  CompilerInvocation::setLangDefaults(Opts, IK, T, PPOpts, LangStd);
+  if (IK.getFormat() != InputKind::Precompiled &&
+      IK.getLanguage() != Language::LLVM_IR)
+    CompilerInvocation::setLangDefaults(Opts, IK, T, PPOpts, LangStd);
 
   // -cl-strict-aliasing needs to emit diagnostic in the case where CL > 1.0.
   // This option should be deprecated for CL > 1.0 because
@@ -3764,32 +3770,16 @@
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
                         Res.getFileSystemOpts().WorkingDir);
   llvm::Triple T(Res.getTargetOpts().Triple);
-  if (DashX.getFormat() == InputKind::Precompiled ||
-      DashX.getLanguage() == Language::LLVM_IR) {
-    // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
-    // PassManager in BackendUtil.cpp. They need to be initializd no matter
-    // what the input type is.
-    if (Args.hasArg(OPT_fobjc_arc))
-      LangOpts.ObjCAutoRefCount = 1;
-    // PIClevel and PIELevel are needed during code generation and this should be
-    // set regardless of the input type.
-    LangOpts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
-    LangOpts.PIE = Args.hasArg(OPT_pic_is_pie);
-    parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
-                        Diags, LangOpts.Sanitize);
-  } 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, Res.getTargetOpts(),
-                  Res.getPreprocessorOpts(), Diags);
-    if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
-      LangOpts.ObjCExceptions = 1;
-    if (T.isOSDarwin() && DashX.isPreprocessed()) {
-      // Supress the darwin-specific 'stdlibcxx-not-found' diagnostic for
-      // preprocessed input as we don't expect it to be used with -std=libc++
-      // anyway.
-      Res.getDiagnosticOpts().Warnings.push_back("no-stdlibcxx-not-found");
-    }
+  // FIXME: Should we really be calling this for an Language::Asm input?
+  ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(),
+                Res.getPreprocessorOpts(), Diags);
+  if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
+    LangOpts.ObjCExceptions = 1;
+  if (T.isOSDarwin() && DashX.isPreprocessed()) {
+    // Supress the darwin-specific 'stdlibcxx-not-found' diagnostic for
+    // preprocessed input as we don't expect it to be used with -std=libc++
+    // anyway.
+    Res.getDiagnosticOpts().Warnings.push_back("no-stdlibcxx-not-found");
   }
 
   if (Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation()))
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to