Index: clang/lib/Parse/ParseDecl.cpp =================================================================== --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -3004,12 +3004,12 @@ while (1) { bool isInvalid = false; bool isStorageClass = false; - bool isAlreadyConsumed = false; const char *PrevSpec = nullptr; unsigned DiagID = 0; - // This value need to be set when isAlreadyConsumed is set to true. - SourceLocation RangeEnd; + // This value need to be set to the location of the last token id the last + // token of the specifier is already consumed. + SourceLocation ConsumedEnd; // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL // implementation for VS2013 uses _Atomic as an identifier for one of the @@ -3566,8 +3566,7 @@ SourceLocation ExplicitLoc = Loc; SourceLocation CloseParenLoc; ExplicitSpecifier ExplicitSpec(nullptr, ExplicitSpecKind::ResolvedTrue); - isAlreadyConsumed = true; - RangeEnd = ExplicitLoc; + ConsumedEnd = ExplicitLoc; ConsumeToken(); // kw_explicit if (Tok.is(tok::l_paren)) { if (getLangOpts().CPlusPlus2a) { @@ -3575,7 +3574,7 @@ BalancedDelimiterTracker Tracker(*this, tok::l_paren); Tracker.consumeOpen(); ExplicitExpr = ParseConstantExpression(); - RangeEnd = Tok.getLocation(); + ConsumedEnd = Tok.getLocation(); if (ExplicitExpr.isUsable()) { CloseParenLoc = Tok.getLocation(); Tracker.consumeClose(); @@ -3934,10 +3933,7 @@ continue; } - assert(!isAlreadyConsumed || RangeEnd != SourceLocation() && - "both or neither of isAlreadyConsumed and " - "RangeEnd needs to be set"); - DS.SetRangeEnd(isAlreadyConsumed ? RangeEnd : Tok.getLocation()); + DS.SetRangeEnd(ConsumedEnd.isValid() ? ConsumedEnd : Tok.getLocation()); // If the specifier wasn't legal, issue a diagnostic. if (isInvalid) { @@ -3958,7 +3954,7 @@ Diag(Loc, DiagID) << PrevSpec; } - if (DiagID != diag::err_bool_redeclaration && !isAlreadyConsumed) + if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.isInvalid()) // After an error the next token can be an annotation token. ConsumeAnyToken();