Hi Richard, This commit has caused an infinite loop in one of our internal libclang based tooling tests. It keeps repeating the following frames:
frame #33528: 0x0000000109db2edf libclang.dylib`clang::DiagnosticsEngine::ReportDelayed(this=0x000000011c002c00) at Diagnostic.cpp:149 frame #33529: 0x0000000109db5a36 libclang.dylib`clang::DiagnosticsEngine::EmitCurrentDiagnostic(this=0x000000011c002c00, Force=false) at Diagnostic.cpp:428 frame #33530: 0x000000010a33f93c libclang.dylib`clang::DiagnosticBuilder::Emit(this=0x0000700008d4bfd8) at Diagnostic.h:1013 frame #33531: 0x000000010a33f8e5 libclang.dylib`clang::DiagnosticBuilder::~DiagnosticBuilder(this=0x0000700008d4bfd8) at Diagnostic.h:1036 frame #33532: 0x000000010a335015 libclang.dylib`clang::DiagnosticBuilder::~DiagnosticBuilder(this=0x0000700008d4bfd8) at Diagnostic.h:1035 It doesn't really look like a regression though, it seems that this has just uncovered a bug in Clang: DiagnosticsEngine::ReportDelayed is clearing DelayedDiagID *after* reporting the issue which causes the infinite recursion, when it should clear it before. Is that right? I will commit a fix for this now. Alex On 3 May 2017 at 01:28, Richard Smith via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: rsmith > Date: Tue May 2 19:28:49 2017 > New Revision: 301992 > > URL: http://llvm.org/viewvc/llvm-project?rev=301992&view=rev > Log: > [modules] Round-trip -Werror flag through explicit module build. > > The intent for an explicit module build is that the diagnostics produced > within > the module are those that were configured when the module was built, not > those > that are enabled within a user of the module. This includes diagnostics > that > don't actually show up until the module is used (for instance, diagnostics > produced during template instantiation and weird cases like -Wpadded). > > We serialized and restored the diagnostic state for individual warning > groups, > but previously did not track the state for flags like -Werror and > -Weverything, > which are implemented as separate bits rather than as part of the > diagnostics > mapping information. > > Modified: > cfe/trunk/include/clang/Basic/Diagnostic.h > cfe/trunk/include/clang/Basic/DiagnosticIDs.h > cfe/trunk/lib/Basic/Diagnostic.cpp > cfe/trunk/lib/Basic/DiagnosticIDs.cpp > cfe/trunk/lib/Serialization/ASTReader.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/test/Index/keep-going.cpp > cfe/trunk/test/Modules/diag-flags.cpp > cfe/trunk/tools/libclang/CIndex.cpp > cfe/trunk/unittests/Basic/DiagnosticTest.cpp > > Modified: cfe/trunk/include/clang/Basic/Diagnostic.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/Diagnostic.h?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/Basic/Diagnostic.h (original) > +++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue May 2 19:28:49 2017 > @@ -178,12 +178,7 @@ public: > > private: > unsigned char AllExtensionsSilenced; // Used by __extension__ > - bool IgnoreAllWarnings; // Ignore all warnings: -w > - bool WarningsAsErrors; // Treat warnings like errors. > - bool EnableAllWarnings; // Enable all warnings. > - bool ErrorsAsFatal; // Treat errors like fatal errors. > - bool FatalsAsError; // Treat fatal errors like errors. > - bool SuppressSystemWarnings; // Suppress warnings in system headers. > + bool SuppressAfterFatalError; // Suppress diagnostics after a fatal > error? > bool SuppressAllDiagnostics; // Suppress all diagnostics. > bool ElideType; // Elide common types of templates. > bool PrintTemplateTree; // Print a tree when comparing templates. > @@ -194,7 +189,6 @@ private: > // 0 -> no limit. > unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr > evaluation > // backtrace stack, 0 -> no limit. > - diag::Severity ExtBehavior; // Map extensions to warnings or > errors? > IntrusiveRefCntPtr<DiagnosticIDs> Diags; > IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; > DiagnosticConsumer *Client; > @@ -216,6 +210,19 @@ private: > llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap; > > public: > + // "Global" configuration state that can actually vary between > modules. > + unsigned IgnoreAllWarnings : 1; // Ignore all warnings: -w > + unsigned EnableAllWarnings : 1; // Enable all warnings. > + unsigned WarningsAsErrors : 1; // Treat warnings like errors. > + unsigned ErrorsAsFatal : 1; // Treat errors like fatal > errors. > + unsigned SuppressSystemWarnings : 1; // Suppress warnings in system > headers. > + diag::Severity ExtBehavior : 4; // Map extensions to warnings or > errors? > + > + DiagState() > + : IgnoreAllWarnings(false), EnableAllWarnings(false), > + WarningsAsErrors(false), ErrorsAsFatal(false), > + SuppressSystemWarnings(false), ExtBehavior(diag::Severity::Ignored) > {} > + > typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator > iterator; > typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator > const_iterator; > @@ -493,33 +500,47 @@ public: > /// \brief When set to true, any unmapped warnings are ignored. > /// > /// If this and WarningsAsErrors are both set, then this one wins. > - void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; } > - bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; } > + void setIgnoreAllWarnings(bool Val) { > + GetCurDiagState()->IgnoreAllWarnings = Val; > + } > + bool getIgnoreAllWarnings() const { > + return GetCurDiagState()->IgnoreAllWarnings; > + } > > /// \brief When set to true, any unmapped ignored warnings are no longer > /// ignored. > /// > /// If this and IgnoreAllWarnings are both set, then that one wins. > - void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; } > - bool getEnableAllWarnings() const { return EnableAllWarnings; } > + void setEnableAllWarnings(bool Val) { > + GetCurDiagState()->EnableAllWarnings = Val; > + } > + bool getEnableAllWarnings() const { > + return GetCurDiagState()->EnableAllWarnings; > + } > > /// \brief When set to true, any warnings reported are issued as errors. > - void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } > - bool getWarningsAsErrors() const { return WarningsAsErrors; } > + void setWarningsAsErrors(bool Val) { > + GetCurDiagState()->WarningsAsErrors = Val; > + } > + bool getWarningsAsErrors() const { > + return GetCurDiagState()->WarningsAsErrors; > + } > > /// \brief When set to true, any error reported is made a fatal error. > - void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; } > - bool getErrorsAsFatal() const { return ErrorsAsFatal; } > + void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = > Val; } > + bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; > } > > - /// \brief When set to true, any fatal error reported is made an error. > - /// > - /// This setting takes precedence over the setErrorsAsFatal setting > above. > - void setFatalsAsError(bool Val) { FatalsAsError = Val; } > - bool getFatalsAsError() const { return FatalsAsError; } > + /// \brief When set to true (the default), suppress further diagnostics > after > + /// a fatal error. > + void setSuppressAfterFatalError(bool Val) { SuppressAfterFatalError = > Val; } > > /// \brief When set to true mask warnings that come from system headers. > - void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = > Val; } > - bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; > } > + void setSuppressSystemWarnings(bool Val) { > + GetCurDiagState()->SuppressSystemWarnings = Val; > + } > + bool getSuppressSystemWarnings() const { > + return GetCurDiagState()->SuppressSystemWarnings; > + } > > /// \brief Suppress all diagnostics, to silence the front end when we > /// know that we don't want any more diagnostics to be passed along to > the > @@ -571,11 +592,15 @@ public: > } > > /// \brief Controls whether otherwise-unmapped extension diagnostics are > - /// mapped onto ignore/warning/error. > + /// mapped onto ignore/warning/error. > /// > /// This corresponds to the GCC -pedantic and -pedantic-errors option. > - void setExtensionHandlingBehavior(diag::Severity H) { ExtBehavior = H; > } > - diag::Severity getExtensionHandlingBehavior() const { return > ExtBehavior; } > + void setExtensionHandlingBehavior(diag::Severity H) { > + GetCurDiagState()->ExtBehavior = H; > + } > + diag::Severity getExtensionHandlingBehavior() const { > + return GetCurDiagState()->ExtBehavior; > + } > > /// \brief Counter bumped when an __extension__ block is/ encountered. > /// > > Modified: cfe/trunk/include/clang/Basic/DiagnosticIDs.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/DiagnosticIDs.h?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/Basic/DiagnosticIDs.h (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticIDs.h Tue May 2 19:28:49 2017 > @@ -122,15 +122,21 @@ public: > bool wasUpgradedFromWarning() const { return WasUpgradedFromWarning; } > void setUpgradedFromWarning(bool Value) { WasUpgradedFromWarning = > Value; } > > - /// Serialize the bits that aren't based on context. > - unsigned serializeBits() const { > - return (WasUpgradedFromWarning << 3) | Severity; > + /// Serialize this mapping as a raw integer. > + unsigned serialize() const { > + return (IsUser << 7) | (IsPragma << 6) | (HasNoWarningAsError << 5) | > + (HasNoErrorAsFatal << 4) | (WasUpgradedFromWarning << 3) | > Severity; > } > - static diag::Severity deserializeSeverity(unsigned Bits) { > - return (diag::Severity)(Bits & 0x7); > - } > - static bool deserializeUpgradedFromWarning(unsigned Bits) { > - return Bits >> 3; > + /// Deserialize a mapping. > + static DiagnosticMapping deserialize(unsigned Bits) { > + DiagnosticMapping Result; > + Result.IsUser = (Bits >> 7) & 1; > + Result.IsPragma = (Bits >> 6) & 1; > + Result.HasNoWarningAsError = (Bits >> 5) & 1; > + Result.HasNoErrorAsFatal = (Bits >> 4) & 1; > + Result.WasUpgradedFromWarning = (Bits >> 3) & 1; > + Result.Severity = Bits & 0x7; > + return Result; > } > }; > > > Modified: cfe/trunk/lib/Basic/Diagnostic.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/ > Diagnostic.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Basic/Diagnostic.cpp (original) > +++ cfe/trunk/lib/Basic/Diagnostic.cpp Tue May 2 19:28:49 2017 > @@ -67,18 +67,12 @@ DiagnosticsEngine::DiagnosticsEngine(Int > ArgToStringCookie = nullptr; > > AllExtensionsSilenced = 0; > - IgnoreAllWarnings = false; > - WarningsAsErrors = false; > - EnableAllWarnings = false; > - ErrorsAsFatal = false; > - FatalsAsError = false; > - SuppressSystemWarnings = false; > + SuppressAfterFatalError = true; > SuppressAllDiagnostics = false; > ElideType = true; > PrintTemplateTree = false; > ShowColors = false; > ShowOverloads = Ovl_All; > - ExtBehavior = diag::Severity::Ignored; > > ErrorLimit = 0; > TemplateBacktraceLimit = 0; > @@ -343,8 +337,8 @@ bool DiagnosticsEngine::setDiagnosticGro > return setSeverityForGroup(diag::Flavor::WarningOrError, Group, > diag::Severity::Fatal); > > - // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, > and > - // potentially downgrade anything already mapped to be an error. > + // Otherwise, we want to set the diagnostic mapping's "no > Wfatal-errors" bit, > + // and potentially downgrade anything already mapped to be a fatal > error. > > // Get the diagnostics in this group. > SmallVector<diag::kind, 8> GroupDiags; > > Modified: cfe/trunk/lib/Basic/DiagnosticIDs.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/ > DiagnosticIDs.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (original) > +++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Tue May 2 19:28:49 2017 > @@ -420,7 +420,7 @@ DiagnosticIDs::getDiagnosticSeverity(uns > Result = Mapping.getSeverity(); > > // Upgrade ignored diagnostics if -Weverything is enabled. > - if (Diag.EnableAllWarnings && Result == diag::Severity::Ignored && > + if (State->EnableAllWarnings && Result == diag::Severity::Ignored && > !Mapping.isUser() && getBuiltinDiagClass(DiagID) != CLASS_REMARK) > Result = diag::Severity::Warning; > > @@ -435,7 +435,7 @@ DiagnosticIDs::getDiagnosticSeverity(uns > // For extension diagnostics that haven't been explicitly mapped, check > if we > // should upgrade the diagnostic. > if (IsExtensionDiag && !Mapping.isUser()) > - Result = std::max(Result, Diag.ExtBehavior); > + Result = std::max(Result, State->ExtBehavior); > > // At this point, ignored errors can no longer be upgraded. > if (Result == diag::Severity::Ignored) > @@ -443,28 +443,24 @@ DiagnosticIDs::getDiagnosticSeverity(uns > > // Honor -w, which is lower in priority than pedantic-errors, but > higher than > // -Werror. > - if (Result == diag::Severity::Warning && Diag.IgnoreAllWarnings) > + // FIXME: Under GCC, this also suppresses warnings that have been > mapped to > + // errors by -W flags and #pragma diagnostic. > + if (Result == diag::Severity::Warning && State->IgnoreAllWarnings) > return diag::Severity::Ignored; > > // If -Werror is enabled, map warnings to errors unless explicitly > disabled. > if (Result == diag::Severity::Warning) { > - if (Diag.WarningsAsErrors && !Mapping.hasNoWarningAsError()) > + if (State->WarningsAsErrors && !Mapping.hasNoWarningAsError()) > Result = diag::Severity::Error; > } > > // If -Wfatal-errors is enabled, map errors to fatal unless explicity > // disabled. > if (Result == diag::Severity::Error) { > - if (Diag.ErrorsAsFatal && !Mapping.hasNoErrorAsFatal()) > + if (State->ErrorsAsFatal && !Mapping.hasNoErrorAsFatal()) > Result = diag::Severity::Fatal; > } > > - // If explicitly requested, map fatal errors to errors. > - if (Result == diag::Severity::Fatal) { > - if (Diag.FatalsAsError) > - Result = diag::Severity::Error; > - } > - > // Custom diagnostics always are emitted in system headers. > bool ShowInSystemHeader = > !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)-> > WarnShowInSystemHeader; > @@ -472,7 +468,7 @@ DiagnosticIDs::getDiagnosticSeverity(uns > // If we are in a system header, we ignore it. We look at the > diagnostic class > // because we also want to ignore extensions and warnings in -Werror and > // -pedantic-errors modes, which *map* warnings/extensions to errors. > - if (Diag.SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() > && > + if (State->SuppressSystemWarnings && !ShowInSystemHeader && > Loc.isValid() && > Diag.getSourceManager().isInSystemHeader( > Diag.getSourceManager().getExpansionLoc(Loc))) > return diag::Severity::Ignored; > @@ -632,7 +628,7 @@ bool DiagnosticIDs::ProcessDiag(Diagnost > > // If a fatal error has already been emitted, silence all subsequent > // diagnostics. > - if (Diag.FatalErrorOccurred) { > + if (Diag.FatalErrorOccurred && Diag.SuppressAfterFatalError) { > if (DiagLevel >= DiagnosticIDs::Error && > Diag.Client->IncludeInDiagnosticCounts()) { > ++Diag.NumErrors; > > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ > Serialization/ASTReader.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue May 2 19:28:49 2017 > @@ -5531,14 +5531,8 @@ void ASTReader::ReadPragmaDiagnosticMapp > "Invalid data, not enough diag/map pairs"); > while (Size--) { > unsigned DiagID = Record[Idx++]; > - unsigned SeverityAndUpgradedFromWarning = Record[Idx++]; > - bool WasUpgradedFromWarning = > - DiagnosticMapping::deserializeUpgradedFromWarning( > - SeverityAndUpgradedFromWarning); > DiagnosticMapping NewMapping = > - Diag.makeUserMapping(DiagnosticMapping::deserializeSeverity( > - SeverityAndUpgradedFromWarning), > - Loc); > + DiagnosticMapping::deserialize(Record[Idx++]); > if (!NewMapping.isPragma() && !IncludeNonPragmaStates) > continue; > > @@ -5547,14 +5541,12 @@ void ASTReader::ReadPragmaDiagnosticMapp > // If this mapping was specified as a warning but the severity was > // upgraded due to diagnostic settings, simulate the current > diagnostic > // settings (and use a warning). > - if (WasUpgradedFromWarning && !Mapping.isErrorOrFatal()) { > - Mapping = Diag.makeUserMapping(diag::Severity::Warning, Loc); > - continue; > + if (NewMapping.wasUpgradedFromWarning() && > !Mapping.isErrorOrFatal()) { > + NewMapping.setSeverity(diag::Severity::Warning); > + NewMapping.setUpgradedFromWarning(false); > } > > - // Use the deserialized mapping verbatim. > Mapping = NewMapping; > - Mapping.setUpgradedFromWarning(WasUpgradedFromWarning); > } > return NewState; > }; > @@ -5569,22 +5561,36 @@ void ASTReader::ReadPragmaDiagnosticMapp > DiagStates.push_back(FirstState); > > // Skip the initial diagnostic state from the serialized module. > - assert(Record[0] == 0 && > + assert(Record[1] == 0 && > "Invalid data, unexpected backref in initial state"); > - Idx = 2 + Record[1] * 2; > + Idx = 3 + Record[2] * 2; > assert(Idx < Record.size() && > "Invalid data, not enough state change pairs in initial > state"); > + } else if (F.isModule()) { > + // For an explicit module, preserve the flags from the module build > + // command line (-w, -Weverything, -Werror, ...) along with any > explicit > + // -Wblah flags. > + unsigned Flags = Record[Idx++]; > + DiagState Initial; > + Initial.SuppressSystemWarnings = Flags & 1; Flags >>= 1; > + Initial.ErrorsAsFatal = Flags & 1; Flags >>= 1; > + Initial.WarningsAsErrors = Flags & 1; Flags >>= 1; > + Initial.EnableAllWarnings = Flags & 1; Flags >>= 1; > + Initial.IgnoreAllWarnings = Flags & 1; Flags >>= 1; > + Initial.ExtBehavior = (diag::Severity)Flags; > + FirstState = ReadDiagState(Initial, SourceLocation(), true); > + > + // Set up the root buffer of the module to start with the initial > + // diagnostic state of the module itself, to cover files that > contain no > + // explicit transitions (for which we did not serialize anything). > + Diag.DiagStatesByLoc.Files[F.OriginalSourceFileID] > + .StateTransitions.push_back({FirstState, 0}); > } else { > - FirstState = ReadDiagState( > - F.isModule() ? DiagState() : *Diag.DiagStatesByLoc. > CurDiagState, > - SourceLocation(), F.isModule()); > - > - // For an explicit module, set up the root buffer of the module to > start > - // with the initial diagnostic state of the module itself, to cover > files > - // that contain no explicit transitions. > - if (F.isModule()) > - Diag.DiagStatesByLoc.Files[F.OriginalSourceFileID] > - .StateTransitions.push_back({FirstState, 0}); > + // For prefix ASTs, start with whatever the user configured on the > + // command line. > + Idx++; // Skip flags. > + FirstState = ReadDiagState(*Diag.DiagStatesByLoc.CurDiagState, > + SourceLocation(), false); > } > > // Read the state transitions. > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ > Serialization/ASTWriter.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue May 2 19:28:49 2017 > @@ -2868,8 +2868,26 @@ void ASTWriter::WritePragmaDiagnosticMap > unsigned CurrID = 0; > RecordData Record; > > + auto EncodeDiagStateFlags = > + [](const DiagnosticsEngine::DiagState *DS) -> unsigned { > + unsigned Result = (unsigned)DS->ExtBehavior; > + for (unsigned Val : > + {DS->IgnoreAllWarnings, DS->EnableAllWarnings, > DS->WarningsAsErrors, > + DS->ErrorsAsFatal, DS->SuppressSystemWarnings}) > + Result = (Result << 1) | Val; > + return Result; > + }; > + > + unsigned Flags = EncodeDiagStateFlags(Diag.DiagStatesByLoc. > FirstDiagState); > + Record.push_back(Flags); > + > auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State, > bool IncludeNonPragmaStates) { > + // Ensure that the diagnostic state wasn't modified since it was > created. > + // We will not correctly round-trip this information otherwise. > + assert(Flags == EncodeDiagStateFlags(State) && > + "diag state flags vary in single AST file"); > + > unsigned &DiagStateID = DiagStateIDMap[State]; > Record.push_back(DiagStateID); > > @@ -2882,7 +2900,7 @@ void ASTWriter::WritePragmaDiagnosticMap > for (const auto &I : *State) { > if (I.second.isPragma() || IncludeNonPragmaStates) { > Record.push_back(I.first); > - Record.push_back(I.second.serializeBits()); > + Record.push_back(I.second.serialize()); > } > } > // Update the placeholder. > > Modified: cfe/trunk/test/Index/keep-going.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/ > keep-going.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/test/Index/keep-going.cpp (original) > +++ cfe/trunk/test/Index/keep-going.cpp Tue May 2 19:28:49 2017 > @@ -25,5 +25,5 @@ class C : public A<float> { }; > // CHECK: C++ base class specifier=A<float>:4:7 [access=public > isVirtual=false] [type=A<float>] [typekind=Unexposed] [templateargs/1= > [type=float] [typekind=Float]] [canonicaltype=A<float>] > [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=float] > [typekind=Float]] [isPOD=0] [nbFields=1] > // CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0] > > -// CHECK-DIAG: keep-going.cpp:1:10: error: 'missing1.h' file not found > -// CHECK-DIAG: keep-going.cpp:8:10: error: 'missing2.h' file not found > +// CHECK-DIAG: keep-going.cpp:1:10: fatal error: 'missing1.h' file not > found > +// CHECK-DIAG: keep-going.cpp:8:10: fatal error: 'missing2.h' file not > found > > Modified: cfe/trunk/test/Modules/diag-flags.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/diag-flags.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/test/Modules/diag-flags.cpp (original) > +++ cfe/trunk/test/Modules/diag-flags.cpp Tue May 2 19:28:49 2017 > @@ -1,20 +1,42 @@ > // RUN: rm -rf %t > // > -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fmodules > -fimplicit-module-maps -emit-module -fmodules-cache-path=%t > -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts > -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts > -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DIMPLICIT_FLAG -Werror=padded > -// > -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fmodules > -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ > %S/Inputs/module.map -fmodules-ts -o %t/explicit.pcm > -Werror=string-plus-int -Wpadded > -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm > -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm -Werror=padded > +// For an implicit module, all that matters are the warning flags in the > user. > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -emit-module -fmodules-cache-path=%t > -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -Wpadded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DERROR -Wpadded -Werror > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DERROR -Werror=padded > +// > +// For an explicit module, all that matters are the warning flags in the > module build. > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ > %S/Inputs/module.map -fmodules-ts -o %t/nodiag.pcm > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -fmodule-file=%t/nodiag.pcm -Wpadded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -fmodule-file=%t/nodiag.pcm -Werror -Wpadded > +// > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ > %S/Inputs/module.map -fmodules-ts -o %t/warning.pcm -Wpadded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm -Werror=padded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm -Werror > +// > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ > %S/Inputs/module.map -fmodules-ts -o %t/werror-no-error.pcm -Werror > -Wpadded -Wno-error=padded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm -Wno-padded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm -Werror=padded > +// > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ > %S/Inputs/module.map -fmodules-ts -o %t/error.pcm -Werror=padded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DERROR -fmodule-file=%t/error.pcm -Wno-padded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DERROR -fmodule-file=%t/error.pcm -Wno-error=padded > +// > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ > %S/Inputs/module.map -fmodules-ts -o %t/werror.pcm -Werror -Wpadded > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DERROR -fmodule-file=%t/werror.pcm -Wno-error > +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules > -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s > -fmodules-ts -DERROR -fmodule-file=%t/werror.pcm -Wno-padded > > import diag_flags; > > // Diagnostic flags from the module user make no difference to diagnostics > // emitted within the module when using an explicitly-loaded module. > -#ifdef IMPLICIT_FLAG > +#if ERROR > // expected-error@diag_flags.h:14 {{padding struct}} > -#elif defined(EXPLICIT_FLAG) > +#elif WARNING > // expected-warning@diag_flags.h:14 {{padding struct}} > #else > // expected-no-diagnostics > > Modified: cfe/trunk/tools/libclang/CIndex.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/ > libclang/CIndex.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/tools/libclang/CIndex.cpp (original) > +++ cfe/trunk/tools/libclang/CIndex.cpp Tue May 2 19:28:49 2017 > @@ -3313,7 +3313,7 @@ clang_parseTranslationUnit_Impl(CXIndex > Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); > > if (options & CXTranslationUnit_KeepGoing) > - Diags->setFatalsAsError(true); > + Diags->setSuppressAfterFatalError(false); > > // Recover resources if we crash before exiting this function. > llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, > > Modified: cfe/trunk/unittests/Basic/DiagnosticTest.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ > Basic/DiagnosticTest.cpp?rev=301992&r1=301991&r2=301992&view=diff > ============================================================ > ================== > --- cfe/trunk/unittests/Basic/DiagnosticTest.cpp (original) > +++ cfe/trunk/unittests/Basic/DiagnosticTest.cpp Tue May 2 19:28:49 2017 > @@ -46,27 +46,30 @@ TEST(DiagnosticTest, suppressAndTrap) { > EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred()); > } > > -// Check that FatalsAsErrors works as intended > -TEST(DiagnosticTest, fatalsAsErrors) { > - DiagnosticsEngine Diags(new DiagnosticIDs(), > - new DiagnosticOptions, > - new IgnoringDiagConsumer()); > - Diags.setFatalsAsError(true); > - > - // Diag that would set UncompilableErrorOccurred and ErrorOccurred. > - Diags.Report(diag::err_target_unknown_triple) << "unknown"; > - > - // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred. > - Diags.Report(diag::err_cannot_open_file) << "file" << "error"; > - > - // Diag that would set FatalErrorOccurred > - // (via non-note following a fatal error). > - Diags.Report(diag::warn_mt_message) << "warning"; > - > - EXPECT_TRUE(Diags.hasErrorOccurred()); > - EXPECT_FALSE(Diags.hasFatalErrorOccurred()); > - EXPECT_TRUE(Diags.hasUncompilableErrorOccurred()); > - EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred()); > +// Check that SuppressAfterFatalError works as intended > +TEST(DiagnosticTest, suppressAfterFatalError) { > + for (unsigned Suppress = 0; Suppress != 2; ++Suppress) { > + DiagnosticsEngine Diags(new DiagnosticIDs(), > + new DiagnosticOptions, > + new IgnoringDiagConsumer()); > + Diags.setSuppressAfterFatalError(Suppress); > + > + // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred. > + Diags.Report(diag::err_cannot_open_file) << "file" << "error"; > + > + // Diag that would set FatalErrorOccurred > + // (via non-note following a fatal error). > + Diags.Report(diag::warn_mt_message) << "warning"; > + > + EXPECT_TRUE(Diags.hasErrorOccurred()); > + EXPECT_TRUE(Diags.hasFatalErrorOccurred()); > + EXPECT_TRUE(Diags.hasUncompilableErrorOccurred()); > + EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred()); > + > + // The warning should be emitted and counted only if we're not > suppressing > + // after fatal errors. > + EXPECT_EQ(Diags.getNumWarnings(), Suppress ? 0u : 1u); > + } > } > > } > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits