diff options
Diffstat (limited to 'lib/Sema')
44 files changed, 8992 insertions, 3441 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 213d6fbffffc..f666a9b46384 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -530,44 +530,37 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,    if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))        return; -  // FIXME: Function try block -  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { -    switch (CheckFallThrough(AC)) { -      case UnknownFallThrough: -        break; +  SourceLocation LBrace = Body->getLocStart(), RBrace = Body->getLocEnd(); +  // Either in a function body compound statement, or a function-try-block. +  switch (CheckFallThrough(AC)) { +    case UnknownFallThrough: +      break; -      case MaybeFallThrough: -        if (HasNoReturn) -          S.Diag(Compound->getRBracLoc(), -                 CD.diag_MaybeFallThrough_HasNoReturn); -        else if (!ReturnsVoid) -          S.Diag(Compound->getRBracLoc(), -                 CD.diag_MaybeFallThrough_ReturnsNonVoid); -        break; -      case AlwaysFallThrough: -        if (HasNoReturn) -          S.Diag(Compound->getRBracLoc(), -                 CD.diag_AlwaysFallThrough_HasNoReturn); -        else if (!ReturnsVoid) -          S.Diag(Compound->getRBracLoc(), -                 CD.diag_AlwaysFallThrough_ReturnsNonVoid); -        break; -      case NeverFallThroughOrReturn: -        if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { -          if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { -            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) -              << 0 << FD; -          } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { -            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) -              << 1 << MD; -          } else { -            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); -          } +    case MaybeFallThrough: +      if (HasNoReturn) +        S.Diag(RBrace, CD.diag_MaybeFallThrough_HasNoReturn); +      else if (!ReturnsVoid) +        S.Diag(RBrace, CD.diag_MaybeFallThrough_ReturnsNonVoid); +      break; +    case AlwaysFallThrough: +      if (HasNoReturn) +        S.Diag(RBrace, CD.diag_AlwaysFallThrough_HasNoReturn); +      else if (!ReturnsVoid) +        S.Diag(RBrace, CD.diag_AlwaysFallThrough_ReturnsNonVoid); +      break; +    case NeverFallThroughOrReturn: +      if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { +        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { +          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD; +        } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { +          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD; +        } else { +          S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);          } -        break; -      case NeverFallThrough: -        break; -    } +      } +      break; +    case NeverFallThrough: +      break;    }  } @@ -923,7 +916,7 @@ namespace {        // issue a warn_fallthrough_attr_unreachable for them.        for (const auto *B : *Cfg) {          const Stmt *L = B->getLabel(); -        if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B)) +        if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B).second)            BlockQueue.push_back(B);        } @@ -933,7 +926,7 @@ namespace {          for (CFGBlock::const_succ_iterator I = P->succ_begin(),                                             E = P->succ_end();               I != E; ++I) { -          if (*I && ReachableBlocks.insert(*I)) +          if (*I && ReachableBlocks.insert(*I).second)              BlockQueue.push_back(*I);          }        } @@ -1444,13 +1437,51 @@ struct SortDiagBySourceLocation {  // -Wthread-safety  //===----------------------------------------------------------------------===//  namespace clang { -namespace thread_safety { -namespace { -class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler { +namespace threadSafety { + +class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {    Sema &S;    DiagList Warnings;    SourceLocation FunLocation, FunEndLocation; +  const FunctionDecl *CurrentFunction; +  bool Verbose; + +  OptionalNotes getNotes() const { +    if (Verbose && CurrentFunction) { +      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), +                                S.PDiag(diag::note_thread_warning_in_fun) +                                    << CurrentFunction->getNameAsString()); +      return OptionalNotes(1, FNote); +    } +    return OptionalNotes(); +  } + +  OptionalNotes getNotes(const PartialDiagnosticAt &Note) const { +    OptionalNotes ONS(1, Note); +    if (Verbose && CurrentFunction) { +      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), +                                S.PDiag(diag::note_thread_warning_in_fun) +                                    << CurrentFunction->getNameAsString()); +      ONS.push_back(FNote); +    } +    return ONS; +  } + +  OptionalNotes getNotes(const PartialDiagnosticAt &Note1, +                         const PartialDiagnosticAt &Note2) const { +    OptionalNotes ONS; +    ONS.push_back(Note1); +    ONS.push_back(Note2); +    if (Verbose && CurrentFunction) { +      PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), +                                S.PDiag(diag::note_thread_warning_in_fun) +                                    << CurrentFunction->getNameAsString()); +      ONS.push_back(FNote); +    } +    return ONS; +  } +    // Helper functions    void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName,                          SourceLocation Loc) { @@ -1459,12 +1490,15 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {      if (!Loc.isValid())        Loc = FunLocation;      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName); -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +    Warnings.push_back(DelayedDiag(Warning, getNotes()));    }   public:    ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) -    : S(S), FunLocation(FL), FunEndLocation(FEL) {} +    : S(S), FunLocation(FL), FunEndLocation(FEL), +      CurrentFunction(nullptr), Verbose(false) {} + +  void setVerbose(bool b) { Verbose = b; }    /// \brief Emit all buffered diagnostics in order of sourcelocation.    /// We need to output diagnostics produced while iterating through @@ -1482,12 +1516,14 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {    void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override {      PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)                                           << Loc); -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +    Warnings.push_back(DelayedDiag(Warning, getNotes()));    } +    void handleUnmatchedUnlock(StringRef Kind, Name LockName,                               SourceLocation Loc) override {      warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc);    } +    void handleIncorrectUnlockKind(StringRef Kind, Name LockName,                                   LockKind Expected, LockKind Received,                                   SourceLocation Loc) override { @@ -1496,8 +1532,9 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {      PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)                                           << Kind << LockName << Received                                           << Expected); -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +    Warnings.push_back(DelayedDiag(Warning, getNotes()));    } +    void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {      warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc);    } @@ -1529,10 +1566,10 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {      if (LocLocked.isValid()) {        PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)                                                << Kind); -      Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); +      Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));        return;      } -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +    Warnings.push_back(DelayedDiag(Warning, getNotes()));    }    void handleExclusiveAndShared(StringRef Kind, Name LockName, @@ -1543,7 +1580,7 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {                                      << Kind << LockName);      PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)                                         << Kind << LockName); -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); +    Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));    }    void handleNoMutexHeld(StringRef Kind, const NamedDecl *D, @@ -1556,7 +1593,7 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {                          diag::warn_var_deref_requires_any_lock;      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)        << D->getNameAsString() << getLockKindFromAccessKind(AK)); -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +    Warnings.push_back(DelayedDiag(Warning, getNotes()));    }    void handleMutexNotHeld(StringRef Kind, const NamedDecl *D, @@ -1575,13 +1612,25 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {          case POK_FunctionCall:            DiagID = diag::warn_fun_requires_lock_precise;            break; +        case POK_PassByRef: +          DiagID = diag::warn_guarded_pass_by_reference; +          break; +        case POK_PtPassByRef: +          DiagID = diag::warn_pt_guarded_pass_by_reference; +          break;        }        PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind                                                         << D->getNameAsString()                                                         << LockName << LK);        PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)                                          << *PossibleMatch); -      Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); +      if (Verbose && POK == POK_VarAccess) { +        PartialDiagnosticAt VNote(D->getLocation(), +                                 S.PDiag(diag::note_guarded_by_declared_here) +                                     << D->getNameAsString()); +        Warnings.push_back(DelayedDiag(Warning, getNotes(Note, VNote))); +      } else +        Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));      } else {        switch (POK) {          case POK_VarAccess: @@ -1593,22 +1642,52 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {          case POK_FunctionCall:            DiagID = diag::warn_fun_requires_lock;            break; +        case POK_PassByRef: +          DiagID = diag::warn_guarded_pass_by_reference; +          break; +        case POK_PtPassByRef: +          DiagID = diag::warn_pt_guarded_pass_by_reference; +          break;        }        PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind                                                         << D->getNameAsString()                                                         << LockName << LK); -      Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +      if (Verbose && POK == POK_VarAccess) { +        PartialDiagnosticAt Note(D->getLocation(), +                                 S.PDiag(diag::note_guarded_by_declared_here) +                                     << D->getNameAsString()); +        Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); +      } else +        Warnings.push_back(DelayedDiag(Warning, getNotes()));      }    } + +  virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg, +                                     SourceLocation Loc) override { +    PartialDiagnosticAt Warning(Loc, +        S.PDiag(diag::warn_acquire_requires_negative_cap) +        << Kind << LockName << Neg); +    Warnings.push_back(DelayedDiag(Warning, getNotes())); +  } + +    void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName,                               SourceLocation Loc) override {      PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)                                           << Kind << FunName << LockName); -    Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); +    Warnings.push_back(DelayedDiag(Warning, getNotes())); +  } + +  void enterFunction(const FunctionDecl* FD) override { +    CurrentFunction = FD; +  } + +  void leaveFunction(const FunctionDecl* FD) override { +    CurrentFunction = 0;    }  }; -} +  }  } @@ -1896,11 +1975,13 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,    if (P.enableThreadSafetyAnalysis) {      SourceLocation FL = AC.getDecl()->getLocation();      SourceLocation FEL = AC.getDecl()->getLocEnd(); -    thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL); +    threadSafety::ThreadSafetyReporter Reporter(S, FL, FEL);      if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart()))        Reporter.setIssueBetaWarnings(true); +    if (!Diags.isIgnored(diag::warn_thread_safety_verbose, D->getLocStart())) +      Reporter.setVerbose(true); -    thread_safety::runThreadSafetyAnalysis(AC, Reporter); +    threadSafety::runThreadSafetyAnalysis(AC, Reporter);      Reporter.emitDiagnostics();    } diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index 476a22b628ad..34af6cf63c87 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -206,3 +206,11 @@ bool AttributeList::isKnownToGCC() const {  unsigned AttributeList::getSemanticSpelling() const {    return getInfo(*this).SpellingIndexToSemanticSpelling(*this);  } + +bool AttributeList::hasVariadicArg() const { +  // If the attribute has the maximum number of optional arguments, we will +  // claim that as being variadic. If we someday get an attribute that +  // legitimately bumps up against that maximum, we can use another bit to track +  // whether it's truly variadic or not. +  return getInfo(*this).OptArgs == 15; +} diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 7847d2c36e5b..4a772d8972a9 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -21,6 +21,7 @@ add_clang_library(clangSema    SemaChecking.cpp    SemaCodeComplete.cpp    SemaConsumer.cpp +  SemaCUDA.cpp    SemaDecl.cpp    SemaDeclAttr.cpp    SemaDeclCXX.cpp diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index d7372b7a2768..7bf3e51999b6 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -18,6 +18,7 @@  #include "clang/AST/NestedNameSpecifier.h"  #include "clang/AST/TypeLoc.h"  #include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetInfo.h"  #include "clang/Lex/Preprocessor.h"  #include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!  #include "clang/Sema/LocInfoType.h" @@ -113,6 +114,18 @@ void CXXScopeSpec::MakeGlobal(ASTContext &Context,           "NestedNameSpecifierLoc range computation incorrect");  } +void CXXScopeSpec::MakeSuper(ASTContext &Context, CXXRecordDecl *RD, +                             SourceLocation SuperLoc, +                             SourceLocation ColonColonLoc) { +  Builder.MakeSuper(Context, RD, SuperLoc, ColonColonLoc); + +  Range.setBegin(SuperLoc); +  Range.setEnd(ColonColonLoc); + +  assert(Range == Builder.getSourceRange() && +  "NestedNameSpecifierLoc range computation incorrect"); +} +  void CXXScopeSpec::MakeTrivial(ASTContext &Context,                                  NestedNameSpecifier *Qualifier, SourceRange R) {    Builder.MakeTrivial(Context, Qualifier, R); @@ -159,6 +172,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,                                               SourceLocation ConstQualifierLoc,                                               SourceLocation                                                   VolatileQualifierLoc, +                                             SourceLocation +                                                 RestrictQualifierLoc,                                               SourceLocation MutableLoc,                                               ExceptionSpecificationType                                                   ESpecType, @@ -167,6 +182,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,                                               SourceRange *ExceptionRanges,                                               unsigned NumExceptions,                                               Expr *NoexceptExpr, +                                             CachedTokens *ExceptionSpecTokens,                                               SourceLocation LocalRangeBegin,                                               SourceLocation LocalRangeEnd,                                               Declarator &TheDeclarator, @@ -193,6 +209,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,    I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();    I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();    I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding(); +  I.Fun.RestrictQualifierLoc    = RestrictQualifierLoc.getRawEncoding();    I.Fun.MutableLoc              = MutableLoc.getRawEncoding();    I.Fun.ExceptionSpecType       = ESpecType;    I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding(); @@ -203,6 +220,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,                                    TrailingReturnType.isInvalid();    I.Fun.TrailingReturnType      = TrailingReturnType.get(); +  assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow"); +  assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow"); +    // new[] a parameter array if needed.    if (NumParams) {      // If the 'InlineParams' in Declarator is unused and big enough, put our @@ -239,6 +259,10 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,    case EST_ComputedNoexcept:      I.Fun.NoexceptExpr = NoexceptExpr;      break; + +  case EST_Unparsed: +    I.Fun.ExceptionSpecTokens = ExceptionSpecTokens; +    break;    }    return I;  } @@ -484,14 +508,14 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,      case SCS_private_extern:      case SCS_static:          if (S.getLangOpts().OpenCLVersion < 120) { -          DiagID   = diag::err_not_opencl_storage_class_specifier; +          DiagID   = diag::err_opencl_unknown_type_specifier;            PrevSpec = getSpecifierName(SC);            return true;          }          break;      case SCS_auto:      case SCS_register: -      DiagID   = diag::err_not_opencl_storage_class_specifier; +      DiagID   = diag::err_opencl_unknown_type_specifier;        PrevSpec = getSpecifierName(SC);        return true;      default: @@ -553,12 +577,6 @@ bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,    else if (W != TSW_longlong || TypeSpecWidth != TSW_long)      return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);    TypeSpecWidth = W; -  if (TypeAltiVecVector && !TypeAltiVecBool && -      ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { -    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); -    DiagID = diag::warn_vector_long_decl_spec_combination; -    return true; -  }    return false;  } @@ -680,11 +698,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,    }    TypeSpecType = T;    TypeSpecOwned = false; -  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { -    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy); -    DiagID = diag::err_invalid_vector_decl_spec; -    return true; -  }    return false;  } @@ -978,6 +991,16 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli        if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||            (TypeSpecWidth != TSW_unspecified))          TypeSpecSign = TSS_unsigned; +    } else if (TypeSpecType == TST_double) { +      // vector long double and vector long long double are never allowed. +      // vector double is OK for Power7 and later. +      if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong) +        Diag(D, TSWLoc, diag::err_invalid_vector_long_double_decl_spec); +      else if (!PP.getTargetInfo().hasFeature("vsx")) +        Diag(D, TSTLoc, diag::err_invalid_vector_double_decl_spec); +    } else if (TypeSpecWidth == TSW_long) { +      Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination) +        << getSpecifierName((TST)TypeSpecType, Policy);      }      if (TypeAltiVecPixel) { diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp index 2a5bacff0d93..6586fb32787c 100644 --- a/lib/Sema/IdentifierResolver.cpp +++ b/lib/Sema/IdentifierResolver.cpp @@ -130,6 +130,9 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,      return false;    } +  // FIXME: If D is a local extern declaration, this check doesn't make sense; +  // we should be checking its lexical context instead in that case, because +  // that is its scope.    DeclContext *DCtx = D->getDeclContext()->getRedeclContext();    return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)                                : Ctx->Equals(DCtx); diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 255845282dfa..fd75c02bb1ed 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -84,6 +84,7 @@ private:    void CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,                   unsigned JumpDiag, unsigned JumpDiagWarning,                   unsigned JumpDiagCXX98Compat); +  void CheckGotoStmt(GotoStmt *GS);    unsigned GetDeepestCommonScope(unsigned A, unsigned B);  }; @@ -489,10 +490,14 @@ void JumpScopeChecker::VerifyJumps() {      // With a goto,      if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) { -      CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(), -                diag::err_goto_into_protected_scope, -                diag::ext_goto_into_protected_scope, -                diag::warn_cxx98_compat_goto_into_protected_scope); +      // The label may not have a statement if it's coming from inline MS ASM. +      if (GS->getLabel()->getStmt()) { +        CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(), +                  diag::err_goto_into_protected_scope, +                  diag::ext_goto_into_protected_scope, +                  diag::warn_cxx98_compat_goto_into_protected_scope); +      } +      CheckGotoStmt(GS);        continue;      } @@ -789,6 +794,15 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,    }  } +void JumpScopeChecker::CheckGotoStmt(GotoStmt *GS) { +  if (GS->getLabel()->isMSAsmLabel()) { +    S.Diag(GS->getGotoLoc(), diag::err_goto_ms_asm_label) +        << GS->getLabel()->getIdentifier(); +    S.Diag(GS->getLabel()->getLocation(), diag::note_goto_ms_asm_label) +        << GS->getLabel()->getIdentifier(); +  } +} +  void Sema::DiagnoseInvalidJumps(Stmt *Body) {    (void)JumpScopeChecker(Body, *this);  } diff --git a/lib/Sema/MultiplexExternalSemaSource.cpp b/lib/Sema/MultiplexExternalSemaSource.cpp index 97237dbf097d..449ddf43114d 100644 --- a/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/lib/Sema/MultiplexExternalSemaSource.cpp @@ -242,6 +242,12 @@ void MultiplexExternalSemaSource::ReadDynamicClasses(      Sources[i]->ReadDynamicClasses(Decls);  } +void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates( +    llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) { +  for(size_t i = 0; i < Sources.size(); ++i) +    Sources[i]->ReadUnusedLocalTypedefNameCandidates(Decls); +} +  void MultiplexExternalSemaSource::ReadLocallyScopedExternCDecls(                                             SmallVectorImpl<NamedDecl*> &Decls) {    for(size_t i = 0; i < Sources.size(); ++i) diff --git a/lib/Sema/Scope.cpp b/lib/Sema/Scope.cpp index 35e2075b3826..6c7977882386 100644 --- a/lib/Sema/Scope.cpp +++ b/lib/Sema/Scope.cpp @@ -39,9 +39,6 @@ void Scope::Init(Scope *parent, unsigned flags) {      BlockParent    = parent->BlockParent;      TemplateParamParent = parent->TemplateParamParent;      MSLocalManglingParent = parent->MSLocalManglingParent; -    SEHTryParent = parent->SEHTryParent; -    if (parent->Flags & SEHTryScope) -      SEHTryParent = parent;      if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |                    FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==          0) @@ -50,17 +47,13 @@ void Scope::Init(Scope *parent, unsigned flags) {      Depth = 0;      PrototypeDepth = 0;      PrototypeIndex = 0; -    SEHTryParent = MSLocalManglingParent = FnParent = BlockParent = nullptr; +    MSLocalManglingParent = FnParent = BlockParent = nullptr;      TemplateParamParent = nullptr;      MSLocalManglingNumber = 1;    }    // If this scope is a function or contains breaks/continues, remember it.    if (flags & FnScope)            FnParent = this; -  SEHTryIndexPool = 0; -  SEHTryIndex = -1; -  if (flags & SEHTryScope) -    SEHTryIndex = FnParent ? FnParent->SEHTryIndexPool++ : -1;    // The MS mangler uses the number of scopes that can hold declarations as    // part of an external name.    if (Flags & (ClassScope | FnScope)) { diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp index 4d079e705f62..63ef3b2355fb 100644 --- a/lib/Sema/ScopeInfo.cpp +++ b/lib/Sema/ScopeInfo.cpp @@ -14,6 +14,7 @@  #include "clang/Sema/ScopeInfo.h"  #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclObjC.h"  #include "clang/AST/Expr.h"  #include "clang/AST/ExprCXX.h" @@ -38,6 +39,7 @@ void FunctionScopeInfo::Clear() {    ErrorTrap.reset();    PossiblyUnreachableDiags.clear();    WeakObjectUses.clear(); +  ModifiedNonNullParams.clear();  }  static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) { @@ -93,6 +95,21 @@ FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {    return BaseInfoTy(D, IsExact);  } +bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const { +  RecordDecl *RD = nullptr; +  if (auto *LSI = dyn_cast<LambdaScopeInfo>(this)) +    RD = LSI->Lambda; +  else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this)) +    RD = CRSI->TheRecordDecl; + +  if (RD) +    for (auto *FD : RD->fields()) { +      if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT) +        return true; +    } +  return false; +} +  FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(                                            const ObjCPropertyRefExpr *PropE)      : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) { @@ -159,6 +176,8 @@ void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {    // Has this weak object been seen before?    FunctionScopeInfo::WeakObjectUseMap::iterator Uses;    if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) { +    if (!RefExpr->isObjectReceiver()) +      return;      if (isa<OpaqueValueExpr>(RefExpr->getBase()))       Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));      else { diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 2c653325b37b..b9aaf1616d68 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -69,8 +69,6 @@ PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,  void Sema::ActOnTranslationUnitScope(Scope *S) {    TUScope = S;    PushDeclContext(S, Context.getTranslationUnitDecl()); - -  VAListTagName = PP.getIdentifierInfo("__va_list_tag");  }  Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, @@ -90,12 +88,14 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,      CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr),      IsBuildingRecoveryCallExpr(false),      ExprNeedsCleanups(false), LateTemplateParser(nullptr), +    LateTemplateParserCleanup(nullptr),      OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr),      CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),      NSNumberDecl(nullptr),      NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),      NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr),      NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr), +    MSAsmLabelNameCounter(0),      GlobalNewDeleteDeclared(false),      TUKind(TUKind),      NumSFINAEErrors(0), @@ -151,6 +151,10 @@ void Sema::Initialize() {        = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))      ExternalSema->InitializeSema(*this); +  // This needs to happen after ExternalSemaSource::InitializeSema(this) or we +  // will not be able to merge any duplicate __va_list_tag decls correctly. +  VAListTagName = PP.getIdentifierInfo("__va_list_tag"); +    // Initialize predefined 128-bit integer types, if needed.    if (Context.getTargetInfo().hasInt128Type()) {      // If either of the 128-bit integer types are unavailable to name lookup, @@ -241,6 +245,8 @@ Sema::~Sema() {    // Destroys data sharing attributes stack for OpenMP    DestroyDataSharingAttributesStack(); + +  assert(DelayedTypos.empty() && "Uncorrected typos!");  }  /// makeUnavailableInSystemHeader - There is an error in the current @@ -538,7 +544,12 @@ static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD,      if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I))        Complete = M->isDefined() || (M->isPure() && !isa<CXXDestructorDecl>(M));      else if (const FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(*I)) -      Complete = F->getTemplatedDecl()->isDefined(); +      // If the template function is marked as late template parsed at this point, +      // it has not been instantiated and therefore we have not performed semantic +      // analysis on it yet, so we cannot know if the type can be considered +      // complete. +      Complete = !F->getTemplatedDecl()->isLateTemplateParsed() && +                  F->getTemplatedDecl()->isDefined();      else if (const CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(*I)) {        if (R->isInjectedClassName())          continue; @@ -591,6 +602,19 @@ static bool IsRecordFullyDefined(const CXXRecordDecl *RD,    return Complete;  } +void Sema::emitAndClearUnusedLocalTypedefWarnings() { +  if (ExternalSource) +    ExternalSource->ReadUnusedLocalTypedefNameCandidates( +        UnusedLocalTypedefNameCandidates); +  for (const TypedefNameDecl *TD : UnusedLocalTypedefNameCandidates) { +    if (TD->isReferenced()) +      continue; +    Diag(TD->getLocation(), diag::warn_unused_local_typedef) +        << isa<TypeAliasDecl>(TD) << TD->getDeclName(); +  } +  UnusedLocalTypedefNameCandidates.clear(); +} +  /// ActOnEndOfTranslationUnit - This is called at the very end of the  /// translation unit when EOF is reached and all but the top-level scope is  /// popped. @@ -647,13 +671,16 @@ void Sema::ActOnEndOfTranslationUnit() {      }      PerformPendingInstantiations(); +    if (LateTemplateParserCleanup) +      LateTemplateParserCleanup(OpaqueParser); +      CheckDelayedMemberExceptionSpecs();    }    // All delayed member exception specs should be checked or we end up accepting    // incompatible declarations.    assert(DelayedDefaultedMemberExceptionSpecs.empty()); -  assert(DelayedDestructorExceptionSpecChecks.empty()); +  assert(DelayedExceptionSpecChecks.empty());    // Remove file scoped decls that turned out to be used.    UnusedFileScopedDecls.erase( @@ -713,6 +740,10 @@ void Sema::ActOnEndOfTranslationUnit() {        }      } +    // Warnings emitted in ActOnEndOfTranslationUnit() should be emitted for +    // modules when they are built, not every time they are used. +    emitAndClearUnusedLocalTypedefWarnings(); +      // Modules don't need any of the checking below.      TUScope = nullptr;      return; @@ -740,7 +771,7 @@ void Sema::ActOnEndOfTranslationUnit() {      // If the tentative definition was completed, getActingDefinition() returns      // null. If we've already seen this variable before, insert()'s second      // return value is false. -    if (!VD || VD->isInvalidDecl() || !Seen.insert(VD)) +    if (!VD || VD->isInvalidDecl() || !Seen.insert(VD).second)        continue;      if (const IncompleteArrayType *ArrayT @@ -788,8 +819,9 @@ void Sema::ActOnEndOfTranslationUnit() {                  !FD->isInlineSpecified() &&                  !SourceMgr.isInMainFile(                     SourceMgr.getExpansionLoc(FD->getLocation()))) -              Diag(DiagD->getLocation(), diag::warn_unneeded_static_internal_decl) -                << DiagD->getDeclName(); +              Diag(DiagD->getLocation(), +                   diag::warn_unneeded_static_internal_decl) +                  << DiagD->getDeclName();              else                Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)                     << /*function*/0 << DiagD->getDeclName(); @@ -820,6 +852,8 @@ void Sema::ActOnEndOfTranslationUnit() {      if (ExternalSource)        ExternalSource->ReadUndefinedButUsed(UndefinedButUsed);      checkUndefinedButUsed(*this); + +    emitAndClearUnusedLocalTypedefWarnings();    }    if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) { @@ -1432,8 +1466,8 @@ IdentifierInfo *Sema::getFloat128Identifier() const {  void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD,                                     CapturedRegionKind K) { -  CapturingScopeInfo *CSI = new CapturedRegionScopeInfo(getDiagnostics(), S, CD, RD, -                                                        CD->getContextParam(), K); +  CapturingScopeInfo *CSI = new CapturedRegionScopeInfo( +      getDiagnostics(), S, CD, RD, CD->getContextParam(), K);    CSI->ReturnType = Context.VoidTy;    FunctionScopes.push_back(CSI);  } diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index ffdb0aa27a6b..37240c23b691 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1749,14 +1749,14 @@ Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {      return AR_accessible;    CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction()); -  assert(method->getQualifier());    AccessTarget entity(Context, AccessTarget::Member,                        cast<CXXRecordDecl>(target->getDeclContext()),                        DeclAccessPair::make(target, access),                        /*no instance context*/ QualType());    entity.setDiag(diag::err_access_friend_function) -    << method->getQualifierLoc().getSourceRange(); +      << (method->getQualifier() ? method->getQualifierLoc().getSourceRange() +                                 : method->getNameInfo().getSourceRange());    // We need to bypass delayed-diagnostics because we might be called    // while the ParsingDeclarator is active. diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index a7d606d545ca..76297977ea0e 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -360,18 +360,18 @@ void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,    }  } -bool Sema::UnifySection(const StringRef &SectionName, +bool Sema::UnifySection(StringRef SectionName,                          int SectionFlags,                          DeclaratorDecl *Decl) { -  auto Section = SectionInfos.find(SectionName); -  if (Section == SectionInfos.end()) { -    SectionInfos[SectionName] = -        SectionInfo(Decl, SourceLocation(), SectionFlags); +  auto Section = Context.SectionInfos.find(SectionName); +  if (Section == Context.SectionInfos.end()) { +    Context.SectionInfos[SectionName] = +        ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);      return false;    }    // A pre-declared section takes precedence w/o diagnostic.    if (Section->second.SectionFlags == SectionFlags || -      !(Section->second.SectionFlags & PSF_Implicit)) +      !(Section->second.SectionFlags & ASTContext::PSF_Implicit))      return false;    auto OtherDecl = Section->second.Decl;    Diag(Decl->getLocation(), diag::err_section_conflict) @@ -384,17 +384,17 @@ bool Sema::UnifySection(const StringRef &SectionName,    if (auto A = OtherDecl->getAttr<SectionAttr>())      if (A->isImplicit())        Diag(A->getLocation(), diag::note_pragma_entered_here); -  return false; +  return true;  } -bool Sema::UnifySection(const StringRef &SectionName, +bool Sema::UnifySection(StringRef SectionName,                          int SectionFlags,                          SourceLocation PragmaSectionLocation) { -  auto Section = SectionInfos.find(SectionName); -  if (Section != SectionInfos.end()) { +  auto Section = Context.SectionInfos.find(SectionName); +  if (Section != Context.SectionInfos.end()) {      if (Section->second.SectionFlags == SectionFlags)        return false; -    if (!(Section->second.SectionFlags & PSF_Implicit)) { +    if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {        Diag(PragmaSectionLocation, diag::err_section_conflict)            << "this" << "a prior #pragma section";        Diag(Section->second.PragmaSectionLocation, @@ -402,8 +402,8 @@ bool Sema::UnifySection(const StringRef &SectionName,        return true;      }    } -  SectionInfos[SectionName] = -      SectionInfo(nullptr, PragmaSectionLocation, SectionFlags); +  Context.SectionInfos[SectionName] = +      ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);    return false;  } diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp new file mode 100644 index 000000000000..64222fbf8ac8 --- /dev/null +++ b/lib/Sema/SemaCUDA.cpp @@ -0,0 +1,263 @@ +//===--- SemaCUDA.cpp - Semantic Analysis for CUDA constructs -------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// \brief This file implements semantic analysis for CUDA constructs. +/// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/Sema.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Sema/SemaDiagnostic.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +using namespace clang; + +ExprResult Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, +                                         MultiExprArg ExecConfig, +                                         SourceLocation GGGLoc) { +  FunctionDecl *ConfigDecl = Context.getcudaConfigureCallDecl(); +  if (!ConfigDecl) +    return ExprError(Diag(LLLLoc, diag::err_undeclared_var_use) +                     << "cudaConfigureCall"); +  QualType ConfigQTy = ConfigDecl->getType(); + +  DeclRefExpr *ConfigDR = new (Context) +      DeclRefExpr(ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc); +  MarkFunctionReferenced(LLLLoc, ConfigDecl); + +  return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, nullptr, +                       /*IsExecConfig=*/true); +} + +/// IdentifyCUDATarget - Determine the CUDA compilation target for this function +Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { +  if (D->hasAttr<CUDAInvalidTargetAttr>()) +    return CFT_InvalidTarget; + +  if (D->hasAttr<CUDAGlobalAttr>()) +    return CFT_Global; + +  if (D->hasAttr<CUDADeviceAttr>()) { +    if (D->hasAttr<CUDAHostAttr>()) +      return CFT_HostDevice; +    return CFT_Device; +  } else if (D->hasAttr<CUDAHostAttr>()) { +    return CFT_Host; +  } else if (D->isImplicit()) { +    // Some implicit declarations (like intrinsic functions) are not marked. +    // Set the most lenient target on them for maximal flexibility. +    return CFT_HostDevice; +  } + +  return CFT_Host; +} + +bool Sema::CheckCUDATarget(const FunctionDecl *Caller, +                           const FunctionDecl *Callee) { +  CUDAFunctionTarget CallerTarget = IdentifyCUDATarget(Caller), +                     CalleeTarget = IdentifyCUDATarget(Callee); + +  // If one of the targets is invalid, the check always fails, no matter what +  // the other target is. +  if (CallerTarget == CFT_InvalidTarget || CalleeTarget == CFT_InvalidTarget) +    return true; + +  // CUDA B.1.1 "The __device__ qualifier declares a function that is [...] +  // Callable from the device only." +  if (CallerTarget == CFT_Host && CalleeTarget == CFT_Device) +    return true; + +  // CUDA B.1.2 "The __global__ qualifier declares a function that is [...] +  // Callable from the host only." +  // CUDA B.1.3 "The __host__ qualifier declares a function that is [...] +  // Callable from the host only." +  if ((CallerTarget == CFT_Device || CallerTarget == CFT_Global) && +      (CalleeTarget == CFT_Host || CalleeTarget == CFT_Global)) +    return true; + +  // CUDA B.1.3 "The __device__ and __host__ qualifiers can be used together +  // however, in which case the function is compiled for both the host and the +  // device. The __CUDA_ARCH__ macro [...] can be used to differentiate code +  // paths between host and device." +  if (CallerTarget == CFT_HostDevice && CalleeTarget != CFT_HostDevice) { +    // If the caller is implicit then the check always passes. +    if (Caller->isImplicit()) return false; + +    bool InDeviceMode = getLangOpts().CUDAIsDevice; +    if ((InDeviceMode && CalleeTarget != CFT_Device) || +        (!InDeviceMode && CalleeTarget != CFT_Host)) +      return true; +  } + +  return false; +} + +/// When an implicitly-declared special member has to invoke more than one +/// base/field special member, conflicts may occur in the targets of these +/// members. For example, if one base's member __host__ and another's is +/// __device__, it's a conflict. +/// This function figures out if the given targets \param Target1 and +/// \param Target2 conflict, and if they do not it fills in +/// \param ResolvedTarget with a target that resolves for both calls. +/// \return true if there's a conflict, false otherwise. +static bool +resolveCalleeCUDATargetConflict(Sema::CUDAFunctionTarget Target1, +                                Sema::CUDAFunctionTarget Target2, +                                Sema::CUDAFunctionTarget *ResolvedTarget) { +  if (Target1 == Sema::CFT_Global && Target2 == Sema::CFT_Global) { +    // TODO: this shouldn't happen, really. Methods cannot be marked __global__. +    // Clang should detect this earlier and produce an error. Then this +    // condition can be changed to an assertion. +    return true; +  } + +  if (Target1 == Sema::CFT_HostDevice) { +    *ResolvedTarget = Target2; +  } else if (Target2 == Sema::CFT_HostDevice) { +    *ResolvedTarget = Target1; +  } else if (Target1 != Target2) { +    return true; +  } else { +    *ResolvedTarget = Target1; +  } + +  return false; +} + +bool Sema::inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, +                                                   CXXSpecialMember CSM, +                                                   CXXMethodDecl *MemberDecl, +                                                   bool ConstRHS, +                                                   bool Diagnose) { +  llvm::Optional<CUDAFunctionTarget> InferredTarget; + +  // We're going to invoke special member lookup; mark that these special +  // members are called from this one, and not from its caller. +  ContextRAII MethodContext(*this, MemberDecl); + +  // Look for special members in base classes that should be invoked from here. +  // Infer the target of this member base on the ones it should call. +  // Skip direct and indirect virtual bases for abstract classes. +  llvm::SmallVector<const CXXBaseSpecifier *, 16> Bases; +  for (const auto &B : ClassDecl->bases()) { +    if (!B.isVirtual()) { +      Bases.push_back(&B); +    } +  } + +  if (!ClassDecl->isAbstract()) { +    for (const auto &VB : ClassDecl->vbases()) { +      Bases.push_back(&VB); +    } +  } + +  for (const auto *B : Bases) { +    const RecordType *BaseType = B->getType()->getAs<RecordType>(); +    if (!BaseType) { +      continue; +    } + +    CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); +    Sema::SpecialMemberOverloadResult *SMOR = +        LookupSpecialMember(BaseClassDecl, CSM, +                            /* ConstArg */ ConstRHS, +                            /* VolatileArg */ false, +                            /* RValueThis */ false, +                            /* ConstThis */ false, +                            /* VolatileThis */ false); + +    if (!SMOR || !SMOR->getMethod()) { +      continue; +    } + +    CUDAFunctionTarget BaseMethodTarget = IdentifyCUDATarget(SMOR->getMethod()); +    if (!InferredTarget.hasValue()) { +      InferredTarget = BaseMethodTarget; +    } else { +      bool ResolutionError = resolveCalleeCUDATargetConflict( +          InferredTarget.getValue(), BaseMethodTarget, +          InferredTarget.getPointer()); +      if (ResolutionError) { +        if (Diagnose) { +          Diag(ClassDecl->getLocation(), +               diag::note_implicit_member_target_infer_collision) +              << (unsigned)CSM << InferredTarget.getValue() << BaseMethodTarget; +        } +        MemberDecl->addAttr(CUDAInvalidTargetAttr::CreateImplicit(Context)); +        return true; +      } +    } +  } + +  // Same as for bases, but now for special members of fields. +  for (const auto *F : ClassDecl->fields()) { +    if (F->isInvalidDecl()) { +      continue; +    } + +    const RecordType *FieldType = +        Context.getBaseElementType(F->getType())->getAs<RecordType>(); +    if (!FieldType) { +      continue; +    } + +    CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(FieldType->getDecl()); +    Sema::SpecialMemberOverloadResult *SMOR = +        LookupSpecialMember(FieldRecDecl, CSM, +                            /* ConstArg */ ConstRHS && !F->isMutable(), +                            /* VolatileArg */ false, +                            /* RValueThis */ false, +                            /* ConstThis */ false, +                            /* VolatileThis */ false); + +    if (!SMOR || !SMOR->getMethod()) { +      continue; +    } + +    CUDAFunctionTarget FieldMethodTarget = +        IdentifyCUDATarget(SMOR->getMethod()); +    if (!InferredTarget.hasValue()) { +      InferredTarget = FieldMethodTarget; +    } else { +      bool ResolutionError = resolveCalleeCUDATargetConflict( +          InferredTarget.getValue(), FieldMethodTarget, +          InferredTarget.getPointer()); +      if (ResolutionError) { +        if (Diagnose) { +          Diag(ClassDecl->getLocation(), +               diag::note_implicit_member_target_infer_collision) +              << (unsigned)CSM << InferredTarget.getValue() +              << FieldMethodTarget; +        } +        MemberDecl->addAttr(CUDAInvalidTargetAttr::CreateImplicit(Context)); +        return true; +      } +    } +  } + +  if (InferredTarget.hasValue()) { +    if (InferredTarget.getValue() == CFT_Device) { +      MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context)); +    } else if (InferredTarget.getValue() == CFT_Host) { +      MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context)); +    } else { +      MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context)); +      MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context)); +    } +  } else { +    // If no target was inferred, mark this member as __host__ __device__; +    // it's the least restrictive option that can be invoked from any target. +    MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context)); +    MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context)); +  } + +  return false; +} diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index a70aca2ad86a..3e56e676a15c 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -148,6 +148,9 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,    case NestedNameSpecifier::Global:      return Context.getTranslationUnitDecl(); + +  case NestedNameSpecifier::Super: +    return NNS->getAsRecordDecl();    }    llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); @@ -240,12 +243,43 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,    return true;  } -bool Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc, +bool Sema::ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc,                                          CXXScopeSpec &SS) {    SS.MakeGlobal(Context, CCLoc);    return false;  } +bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc, +                                    SourceLocation ColonColonLoc, +                                    CXXScopeSpec &SS) { +  CXXRecordDecl *RD = nullptr; +  for (Scope *S = getCurScope(); S; S = S->getParent()) { +    if (S->isFunctionScope()) { +      if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S->getEntity())) +        RD = MD->getParent(); +      break; +    } +    if (S->isClassScope()) { +      RD = cast<CXXRecordDecl>(S->getEntity()); +      break; +    } +  } + +  if (!RD) { +    Diag(SuperLoc, diag::err_invalid_super_scope); +    return true; +  } else if (RD->isLambda()) { +    Diag(SuperLoc, diag::err_super_in_lambda_unsupported); +    return true; +  } else if (RD->getNumBases() == 0) { +    Diag(SuperLoc, diag::err_no_base_classes) << RD->getName(); +    return true; +  } + +  SS.MakeSuper(Context, RD, SuperLoc, ColonColonLoc); +  return false; +} +  /// \brief Determines whether the given declaration is an valid acceptable  /// result for name lookup of a nested-name-specifier.  bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD) { @@ -376,9 +410,6 @@ class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback {  /// \brief Build a new nested-name-specifier for "identifier::", as described  /// by ActOnCXXNestedNameSpecifier.  /// -/// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in -/// that it contains an extra parameter \p ScopeLookupResult. -///  /// \param S Scope in which the nested-name-specifier occurs.  /// \param Identifier Identifier in the sequence "identifier" "::".  /// \param IdentifierLoc Location of the \p Identifier. @@ -541,12 +572,11 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,      // We haven't found anything, and we're not recovering from a      // different kind of error, so look for typos.      DeclarationName Name = Found.getLookupName(); -    NestedNameSpecifierValidatorCCC Validator(*this);      Found.clear(); -    if (TypoCorrection Corrected = -            CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, -                        &SS, Validator, CTK_ErrorRecovery, LookupCtx, -                        EnteringContext)) { +    if (TypoCorrection Corrected = CorrectTypo( +            Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, +            llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this), +            CTK_ErrorRecovery, LookupCtx, EnteringContext)) {        if (LookupCtx) {          bool DroppedSpecifier =              Corrected.WillReplaceSpecifier() && @@ -612,10 +642,17 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,         }      } +    if (auto *TD = dyn_cast_or_null<TypedefNameDecl>(SD)) +      MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false); +      // If we're just performing this lookup for error-recovery purposes,      // don't extend the nested-name-specifier. Just return now.      if (ErrorRecoveryLookup)        return false; + +    // The use of a nested name specifier may trigger deprecation warnings. +    DiagnoseUseOfDecl(SD, CCLoc); +      if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) {        SS.Extend(Context, Namespace, IdentifierLoc, CCLoc); @@ -703,8 +740,13 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,    if (getLangOpts().MSVCCompat) {      DeclContext *DC = LookupCtx ? LookupCtx : CurContext;      if (DC->isDependentContext() && DC->isFunctionOrMethod()) { -      SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc); -      return false; +      CXXRecordDecl *ContainingClass = dyn_cast<CXXRecordDecl>(DC->getParent()); +      if (ContainingClass && ContainingClass->hasAnyDependentBases()) { +        Diag(IdentifierLoc, diag::ext_undeclared_unqual_id_with_dependent_base) +            << &Identifier << ContainingClass; +        SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc); +        return false; +      }      }    } @@ -945,6 +987,7 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {    case NestedNameSpecifier::Identifier:    case NestedNameSpecifier::TypeSpec:    case NestedNameSpecifier::TypeSpecWithTemplate: +  case NestedNameSpecifier::Super:      // These are never namespace scopes.      return true;    } diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index ae5436cf415c..a4c2d9b51c26 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -142,9 +142,6 @@ namespace {    };  } -static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, -                               bool CheckCVR, bool CheckObjCLifetime); -  // The Try functions attempt a specific way of casting. If they succeed, they  // return TC_Success. If their way of casting is not appropriate for the given  // arguments, they return TC_NotApplicable and *may* set diag to a diagnostic @@ -243,10 +240,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,    QualType DestType = DestTInfo->getType();    // If the type is dependent, we won't do the semantic analysis now. -  // FIXME: should we check this in a more fine-grained manner? -  bool TypeDependent = DestType->isDependentType() || -                       Ex.get()->isTypeDependent() || -                       Ex.get()->isValueDependent(); +  bool TypeDependent = +      DestType->isDependentType() || Ex.get()->isTypeDependent();    CastOperation Op(*this, DestType, E);    Op.OpRange = SourceRange(OpLoc, Parens.getEnd()); @@ -462,7 +457,10 @@ static bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {  /// \param CheckObjCLifetime Whether to check Objective-C lifetime qualifiers.  static bool  CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, -                   bool CheckCVR, bool CheckObjCLifetime) { +                   bool CheckCVR, bool CheckObjCLifetime, +                   QualType *TheOffendingSrcType = nullptr, +                   QualType *TheOffendingDestType = nullptr, +                   Qualifiers *CastAwayQualifiers = nullptr) {    // If the only checking we care about is for Objective-C lifetime qualifiers,    // and we're not in ARC mode, there's nothing to check.    if (!CheckCVR && CheckObjCLifetime &&  @@ -487,6 +485,8 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType,    // Find the qualifiers. We only care about cvr-qualifiers for the     // purpose of this check, because other qualifiers (address spaces,     // Objective-C GC, etc.) are part of the type's identity. +  QualType PrevUnwrappedSrcType = UnwrappedSrcType; +  QualType PrevUnwrappedDestType = UnwrappedDestType;    while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {      // Determine the relevant qualifiers at this level.      Qualifiers SrcQuals, DestQuals; @@ -497,6 +497,13 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType,      if (CheckCVR) {        RetainedSrcQuals.setCVRQualifiers(SrcQuals.getCVRQualifiers());        RetainedDestQuals.setCVRQualifiers(DestQuals.getCVRQualifiers()); + +      if (RetainedSrcQuals != RetainedDestQuals && TheOffendingSrcType && +          TheOffendingDestType && CastAwayQualifiers) { +        *TheOffendingSrcType = PrevUnwrappedSrcType; +        *TheOffendingDestType = PrevUnwrappedDestType; +        *CastAwayQualifiers = RetainedSrcQuals - RetainedDestQuals; +      }      }      if (CheckObjCLifetime && @@ -505,6 +512,9 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType,      cv1.push_back(RetainedSrcQuals);      cv2.push_back(RetainedDestQuals); + +    PrevUnwrappedSrcType = UnwrappedSrcType; +    PrevUnwrappedDestType = UnwrappedDestType;    }    if (cv1.empty())      return false; @@ -2200,8 +2210,8 @@ void CastOperation::CheckCStyleCast() {    // address space B is illegal.    if (Self.getLangOpts().OpenCL && DestType->isPointerType() &&        SrcType->isPointerType()) { -    if (DestType->getPointeeType().getAddressSpace() != -        SrcType->getPointeeType().getAddressSpace()) { +    const PointerType *DestPtr = DestType->getAs<PointerType>(); +    if (!DestPtr->isAddressSpaceOverlapping(*SrcType->getAs<PointerType>())) {        Self.Diag(OpRange.getBegin(),                  diag::err_typecheck_incompatible_address_space)            << SrcType << DestType << Sema::AA_Casting @@ -2371,6 +2381,30 @@ void CastOperation::CheckCStyleCast() {    if (Kind == CK_BitCast)      checkCastAlign(); + +  // -Wcast-qual +  QualType TheOffendingSrcType, TheOffendingDestType; +  Qualifiers CastAwayQualifiers; +  if (SrcType->isAnyPointerType() && DestType->isAnyPointerType() && +      CastsAwayConstness(Self, SrcType, DestType, true, false, +                         &TheOffendingSrcType, &TheOffendingDestType, +                         &CastAwayQualifiers)) { +    int qualifiers = -1; +    if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) { +      qualifiers = 0; +    } else if (CastAwayQualifiers.hasConst()) { +      qualifiers = 1; +    } else if (CastAwayQualifiers.hasVolatile()) { +      qualifiers = 2; +    } +    // This is a variant of int **x; const int **y = (const int **)x; +    if (qualifiers == -1) +      Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual2) << +        SrcType << DestType; +    else +      Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual) << +        TheOffendingSrcType << TheOffendingDestType << qualifiers; +  }  }  ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 66be962fcf33..9fc2bec23b1b 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -111,8 +111,100 @@ static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) {    return false;  } +static void SemaBuiltinMemChkCall(Sema &S, FunctionDecl *FDecl, +		                  CallExpr *TheCall, unsigned SizeIdx, +                                  unsigned DstSizeIdx) { +  if (TheCall->getNumArgs() <= SizeIdx || +      TheCall->getNumArgs() <= DstSizeIdx) +    return; + +  const Expr *SizeArg = TheCall->getArg(SizeIdx); +  const Expr *DstSizeArg = TheCall->getArg(DstSizeIdx); + +  llvm::APSInt Size, DstSize; + +  // find out if both sizes are known at compile time +  if (!SizeArg->EvaluateAsInt(Size, S.Context) || +      !DstSizeArg->EvaluateAsInt(DstSize, S.Context)) +    return; + +  if (Size.ule(DstSize)) +    return; + +  // confirmed overflow so generate the diagnostic. +  IdentifierInfo *FnName = FDecl->getIdentifier(); +  SourceLocation SL = TheCall->getLocStart(); +  SourceRange SR = TheCall->getSourceRange(); + +  S.Diag(SL, diag::warn_memcpy_chk_overflow) << SR << FnName; +} + +static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) { +  if (checkArgCount(S, BuiltinCall, 2)) +    return true; + +  SourceLocation BuiltinLoc = BuiltinCall->getLocStart(); +  Expr *Builtin = BuiltinCall->getCallee()->IgnoreImpCasts(); +  Expr *Call = BuiltinCall->getArg(0); +  Expr *Chain = BuiltinCall->getArg(1); + +  if (Call->getStmtClass() != Stmt::CallExprClass) { +    S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call) +        << Call->getSourceRange(); +    return true; +  } + +  auto CE = cast<CallExpr>(Call); +  if (CE->getCallee()->getType()->isBlockPointerType()) { +    S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call) +        << Call->getSourceRange(); +    return true; +  } + +  const Decl *TargetDecl = CE->getCalleeDecl(); +  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) +    if (FD->getBuiltinID()) { +      S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call) +          << Call->getSourceRange(); +      return true; +    } + +  if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) { +    S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call) +        << Call->getSourceRange(); +    return true; +  } + +  ExprResult ChainResult = S.UsualUnaryConversions(Chain); +  if (ChainResult.isInvalid()) +    return true; +  if (!ChainResult.get()->getType()->isPointerType()) { +    S.Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer) +        << Chain->getSourceRange(); +    return true; +  } + +  QualType ReturnTy = CE->getCallReturnType(); +  QualType ArgTys[2] = { ReturnTy, ChainResult.get()->getType() }; +  QualType BuiltinTy = S.Context.getFunctionType( +      ReturnTy, ArgTys, FunctionProtoType::ExtProtoInfo()); +  QualType BuiltinPtrTy = S.Context.getPointerType(BuiltinTy); + +  Builtin = +      S.ImpCastExprToType(Builtin, BuiltinPtrTy, CK_BuiltinFnToFnPtr).get(); + +  BuiltinCall->setType(CE->getType()); +  BuiltinCall->setValueKind(CE->getValueKind()); +  BuiltinCall->setObjectKind(CE->getObjectKind()); +  BuiltinCall->setCallee(Builtin); +  BuiltinCall->setArg(1, ChainResult.get()); + +  return false; +} +  ExprResult -Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { +Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, +                               CallExpr *TheCall) {    ExprResult TheCallResult(TheCall);    // Find out if any arguments are required to be integer constant expressions. @@ -189,9 +281,14 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {        return ExprError();      break;    case Builtin::BI__assume: +  case Builtin::BI__builtin_assume:      if (SemaBuiltinAssume(TheCall))        return ExprError();      break; +  case Builtin::BI__builtin_assume_aligned: +    if (SemaBuiltinAssumeAligned(TheCall)) +      return ExprError(); +    break;    case Builtin::BI__builtin_object_size:      if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))        return ExprError(); @@ -239,6 +336,12 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {    case Builtin::BI__sync_fetch_and_xor_4:    case Builtin::BI__sync_fetch_and_xor_8:    case Builtin::BI__sync_fetch_and_xor_16: +  case Builtin::BI__sync_fetch_and_nand: +  case Builtin::BI__sync_fetch_and_nand_1: +  case Builtin::BI__sync_fetch_and_nand_2: +  case Builtin::BI__sync_fetch_and_nand_4: +  case Builtin::BI__sync_fetch_and_nand_8: +  case Builtin::BI__sync_fetch_and_nand_16:    case Builtin::BI__sync_add_and_fetch:    case Builtin::BI__sync_add_and_fetch_1:    case Builtin::BI__sync_add_and_fetch_2: @@ -269,6 +372,12 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {    case Builtin::BI__sync_xor_and_fetch_4:    case Builtin::BI__sync_xor_and_fetch_8:    case Builtin::BI__sync_xor_and_fetch_16: +  case Builtin::BI__sync_nand_and_fetch: +  case Builtin::BI__sync_nand_and_fetch_1: +  case Builtin::BI__sync_nand_and_fetch_2: +  case Builtin::BI__sync_nand_and_fetch_4: +  case Builtin::BI__sync_nand_and_fetch_8: +  case Builtin::BI__sync_nand_and_fetch_16:    case Builtin::BI__sync_val_compare_and_swap:    case Builtin::BI__sync_val_compare_and_swap_1:    case Builtin::BI__sync_val_compare_and_swap_2: @@ -327,6 +436,31 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {      // so ensure that they are declared.      DeclareGlobalNewDelete();      break; + +  // check secure string manipulation functions where overflows +  // are detectable at compile time +  case Builtin::BI__builtin___memcpy_chk: +  case Builtin::BI__builtin___memmove_chk: +  case Builtin::BI__builtin___memset_chk: +  case Builtin::BI__builtin___strlcat_chk: +  case Builtin::BI__builtin___strlcpy_chk: +  case Builtin::BI__builtin___strncat_chk: +  case Builtin::BI__builtin___strncpy_chk: +  case Builtin::BI__builtin___stpncpy_chk: +    SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3); +    break; +  case Builtin::BI__builtin___memccpy_chk: +    SemaBuiltinMemChkCall(*this, FDecl, TheCall, 3, 4); +    break; +  case Builtin::BI__builtin___snprintf_chk: +  case Builtin::BI__builtin___vsnprintf_chk: +    SemaBuiltinMemChkCall(*this, FDecl, TheCall, 1, 3); +    break; + +  case Builtin::BI__builtin_call_with_static_chain: +    if (SemaBuiltinCallWithStaticChain(*this, TheCall)) +      return ExprError(); +    break;    }    // Since the target specific builtins for each arch overlap, only check those @@ -342,8 +476,6 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {          break;        case llvm::Triple::aarch64:        case llvm::Triple::aarch64_be: -      case llvm::Triple::arm64: -      case llvm::Triple::arm64_be:          if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall))            return ExprError();          break; @@ -468,8 +600,7 @@ bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {      QualType RHSTy = RHS.get()->getType();      llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); -    bool IsPolyUnsigned = -        Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::arm64; +    bool IsPolyUnsigned = Arch == llvm::Triple::aarch64;      bool IsInt64Long =          Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong;      QualType EltTy = @@ -627,6 +758,11 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {      return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64);    } +  if (BuiltinID == ARM::BI__builtin_arm_prefetch) { +    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || +      SemaBuiltinConstantArgRange(TheCall, 2, 0, 1); +  } +    if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))      return true; @@ -641,7 +777,8 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {    case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;    case ARM::BI__builtin_arm_dmb:    case ARM::BI__builtin_arm_dsb: -  case ARM::BI__builtin_arm_isb: l = 0; u = 15; break; +  case ARM::BI__builtin_arm_isb: +  case ARM::BI__builtin_arm_dbg: l = 0; u = 15; break;    }    // FIXME: VFP Intrinsics should error if VFP not present. @@ -659,6 +796,13 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,      return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128);    } +  if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { +    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || +      SemaBuiltinConstantArgRange(TheCall, 2, 0, 2) || +      SemaBuiltinConstantArgRange(TheCall, 3, 0, 1) || +      SemaBuiltinConstantArgRange(TheCall, 4, 0, 1); +  } +    if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))      return true; @@ -672,7 +816,6 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,    case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break;    } -  // FIXME: VFP Intrinsics should error if VFP not present.    return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);  } @@ -693,12 +836,16 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {  }  bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { +  unsigned i = 0, l = 0, u = 0;    switch (BuiltinID) { -  case X86::BI_mm_prefetch: -    // This is declared to take (const char*, int) -    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3); +  default: return false; +  case X86::BI_mm_prefetch: i = 1; l = 0; u = 3; break; +  case X86::BI__builtin_ia32_cmpps: +  case X86::BI__builtin_ia32_cmpss: +  case X86::BI__builtin_ia32_cmppd: +  case X86::BI__builtin_ia32_cmpsd: i = 2; l = 0; u = 31; break;    } -  return false; +  return SemaBuiltinConstantArgRange(TheCall, i, l, u);  }  /// Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo @@ -753,14 +900,79 @@ static void CheckNonNullArgument(Sema &S,      S.Diag(CallSiteLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();  } +bool Sema::GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx) { +  FormatStringInfo FSI; +  if ((GetFormatStringType(Format) == FST_NSString) && +      getFormatStringInfo(Format, false, &FSI)) { +    Idx = FSI.FormatIdx; +    return true; +  } +  return false; +} +/// \brief Diagnose use of %s directive in an NSString which is being passed +/// as formatting string to formatting method. +static void +DiagnoseCStringFormatDirectiveInCFAPI(Sema &S, +                                        const NamedDecl *FDecl, +                                        Expr **Args, +                                        unsigned NumArgs) { +  unsigned Idx = 0; +  bool Format = false; +  ObjCStringFormatFamily SFFamily = FDecl->getObjCFStringFormattingFamily(); +  if (SFFamily == ObjCStringFormatFamily::SFF_CFString) { +    Idx = 2; +    Format = true; +  } +  else +    for (const auto *I : FDecl->specific_attrs<FormatAttr>()) { +      if (S.GetFormatNSStringIdx(I, Idx)) { +        Format = true; +        break; +      } +    } +  if (!Format || NumArgs <= Idx) +    return; +  const Expr *FormatExpr = Args[Idx]; +  if (const CStyleCastExpr *CSCE = dyn_cast<CStyleCastExpr>(FormatExpr)) +    FormatExpr = CSCE->getSubExpr(); +  const StringLiteral *FormatString; +  if (const ObjCStringLiteral *OSL = +      dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) +    FormatString = OSL->getString(); +  else +    FormatString = dyn_cast<StringLiteral>(FormatExpr->IgnoreParenImpCasts()); +  if (!FormatString) +    return; +  if (S.FormatStringHasSArg(FormatString)) { +    S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string) +      << "%s" << 1 << 1; +    S.Diag(FDecl->getLocation(), diag::note_entity_declared_at) +      << FDecl->getDeclName(); +  } +} +  static void CheckNonNullArguments(Sema &S,                                    const NamedDecl *FDecl, -                                  const Expr * const *ExprArgs, +                                  ArrayRef<const Expr *> Args,                                    SourceLocation CallSiteLoc) {    // Check the attributes attached to the method/function itself. +  llvm::SmallBitVector NonNullArgs;    for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) { -    for (const auto &Val : NonNull->args()) -      CheckNonNullArgument(S, ExprArgs[Val], CallSiteLoc); +    if (!NonNull->args_size()) { +      // Easy case: all pointer arguments are nonnull. +      for (const auto *Arg : Args) +        if (S.isValidPointerAttrType(Arg->getType())) +          CheckNonNullArgument(S, Arg, CallSiteLoc); +      return; +    } + +    for (unsigned Val : NonNull->args()) { +      if (Val >= Args.size()) +        continue; +      if (NonNullArgs.empty()) +        NonNullArgs.resize(Args.size()); +      NonNullArgs.set(Val); +    }    }    // Check the attributes on the parameters. @@ -770,13 +982,19 @@ static void CheckNonNullArguments(Sema &S,    else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(FDecl))      parms = MD->parameters(); -  unsigned argIndex = 0; +  unsigned ArgIndex = 0;    for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end(); -       I != E; ++I, ++argIndex) { +       I != E; ++I, ++ArgIndex) {      const ParmVarDecl *PVD = *I; -    if (PVD->hasAttr<NonNullAttr>()) -      CheckNonNullArgument(S, ExprArgs[argIndex], CallSiteLoc); +    if (PVD->hasAttr<NonNullAttr>() || +        (ArgIndex < NonNullArgs.size() && NonNullArgs[ArgIndex])) +      CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc);    } + +  // In case this is a variadic call, check any remaining arguments. +  for (/**/; ArgIndex < NonNullArgs.size(); ++ArgIndex) +    if (NonNullArgs[ArgIndex]) +      CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc);  }  /// Handles the checks for format strings, non-POD arguments to vararg @@ -814,7 +1032,7 @@ void Sema::checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,    }    if (FDecl) { -    CheckNonNullArguments(*this, FDecl, Args.data(), Loc); +    CheckNonNullArguments(*this, FDecl, Args, Loc);      // Type safety checking.      for (const auto *I : FDecl->specific_attrs<ArgumentWithTypeTagAttr>()) @@ -854,7 +1072,7 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,      ++Args;      --NumArgs;    } -  checkCall(FDecl, llvm::makeArrayRef<const Expr *>(Args, NumArgs), NumParams, +  checkCall(FDecl, llvm::makeArrayRef(Args, NumArgs), NumParams,              IsMemberFunction, TheCall->getRParenLoc(),              TheCall->getCallee()->getSourceRange(), CallType); @@ -865,6 +1083,8 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,      return false;    CheckAbsoluteValueFunction(TheCall, FDecl, FnInfo); +  if (getLangOpts().ObjC1) +    DiagnoseCStringFormatDirectiveInCFAPI(*this, FDecl, Args, NumArgs);    unsigned CMId = FDecl->getMemoryFunctionKind();    if (CMId == 0) @@ -913,8 +1133,8 @@ bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,    }    unsigned NumParams = Proto ? Proto->getNumParams() : 0; -  checkCall(NDecl, llvm::makeArrayRef<const Expr *>(TheCall->getArgs(), -                                                    TheCall->getNumArgs()), +  checkCall(NDecl, llvm::makeArrayRef(TheCall->getArgs(), +                                      TheCall->getNumArgs()),              NumParams, /*IsMemberFunction=*/false, TheCall->getRParenLoc(),              TheCall->getCallee()->getSourceRange(), CallType); @@ -929,8 +1149,7 @@ bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) {    unsigned NumParams = Proto ? Proto->getNumParams() : 0;    checkCall(/*FDecl=*/nullptr, -            llvm::makeArrayRef<const Expr *>(TheCall->getArgs(), -                                             TheCall->getNumArgs()), +            llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()),              NumParams, /*IsMemberFunction=*/false, TheCall->getRParenLoc(),              TheCall->getCallee()->getSourceRange(), CallType); @@ -1383,12 +1602,14 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {      BUILTIN_ROW(__sync_fetch_and_or),      BUILTIN_ROW(__sync_fetch_and_and),      BUILTIN_ROW(__sync_fetch_and_xor), +    BUILTIN_ROW(__sync_fetch_and_nand),      BUILTIN_ROW(__sync_add_and_fetch),      BUILTIN_ROW(__sync_sub_and_fetch),      BUILTIN_ROW(__sync_and_and_fetch),      BUILTIN_ROW(__sync_or_and_fetch),      BUILTIN_ROW(__sync_xor_and_fetch), +    BUILTIN_ROW(__sync_nand_and_fetch),      BUILTIN_ROW(__sync_val_compare_and_swap),      BUILTIN_ROW(__sync_bool_compare_and_swap), @@ -1418,6 +1639,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    // as the number of fixed args.    unsigned BuiltinID = FDecl->getBuiltinID();    unsigned BuiltinIndex, NumFixed = 1; +  bool WarnAboutSemanticsChange = false;    switch (BuiltinID) {    default: llvm_unreachable("Unknown overloaded atomic builtin!");    case Builtin::BI__sync_fetch_and_add:  @@ -1465,13 +1687,23 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {      BuiltinIndex = 4;       break; +  case Builtin::BI__sync_fetch_and_nand:  +  case Builtin::BI__sync_fetch_and_nand_1: +  case Builtin::BI__sync_fetch_and_nand_2: +  case Builtin::BI__sync_fetch_and_nand_4: +  case Builtin::BI__sync_fetch_and_nand_8: +  case Builtin::BI__sync_fetch_and_nand_16: +    BuiltinIndex = 5; +    WarnAboutSemanticsChange = true; +    break; +    case Builtin::BI__sync_add_and_fetch:     case Builtin::BI__sync_add_and_fetch_1:    case Builtin::BI__sync_add_and_fetch_2:    case Builtin::BI__sync_add_and_fetch_4:    case Builtin::BI__sync_add_and_fetch_8:    case Builtin::BI__sync_add_and_fetch_16: -    BuiltinIndex = 5;  +    BuiltinIndex = 6;       break;    case Builtin::BI__sync_sub_and_fetch:  @@ -1480,7 +1712,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_sub_and_fetch_4:    case Builtin::BI__sync_sub_and_fetch_8:    case Builtin::BI__sync_sub_and_fetch_16: -    BuiltinIndex = 6;  +    BuiltinIndex = 7;       break;    case Builtin::BI__sync_and_and_fetch:  @@ -1489,7 +1721,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_and_and_fetch_4:    case Builtin::BI__sync_and_and_fetch_8:    case Builtin::BI__sync_and_and_fetch_16: -    BuiltinIndex = 7;  +    BuiltinIndex = 8;       break;    case Builtin::BI__sync_or_and_fetch:   @@ -1498,7 +1730,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_or_and_fetch_4:    case Builtin::BI__sync_or_and_fetch_8:    case Builtin::BI__sync_or_and_fetch_16: -    BuiltinIndex = 8;  +    BuiltinIndex = 9;       break;    case Builtin::BI__sync_xor_and_fetch:  @@ -1507,7 +1739,17 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_xor_and_fetch_4:    case Builtin::BI__sync_xor_and_fetch_8:    case Builtin::BI__sync_xor_and_fetch_16: -    BuiltinIndex = 9;  +    BuiltinIndex = 10; +    break; + +  case Builtin::BI__sync_nand_and_fetch:  +  case Builtin::BI__sync_nand_and_fetch_1: +  case Builtin::BI__sync_nand_and_fetch_2: +  case Builtin::BI__sync_nand_and_fetch_4: +  case Builtin::BI__sync_nand_and_fetch_8: +  case Builtin::BI__sync_nand_and_fetch_16: +    BuiltinIndex = 11; +    WarnAboutSemanticsChange = true;      break;    case Builtin::BI__sync_val_compare_and_swap: @@ -1516,7 +1758,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_val_compare_and_swap_4:    case Builtin::BI__sync_val_compare_and_swap_8:    case Builtin::BI__sync_val_compare_and_swap_16: -    BuiltinIndex = 10; +    BuiltinIndex = 12;      NumFixed = 2;      break; @@ -1526,7 +1768,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_bool_compare_and_swap_4:    case Builtin::BI__sync_bool_compare_and_swap_8:    case Builtin::BI__sync_bool_compare_and_swap_16: -    BuiltinIndex = 11; +    BuiltinIndex = 13;      NumFixed = 2;      ResultType = Context.BoolTy;      break; @@ -1537,7 +1779,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_lock_test_and_set_4:    case Builtin::BI__sync_lock_test_and_set_8:    case Builtin::BI__sync_lock_test_and_set_16: -    BuiltinIndex = 12;  +    BuiltinIndex = 14;       break;    case Builtin::BI__sync_lock_release: @@ -1546,7 +1788,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_lock_release_4:    case Builtin::BI__sync_lock_release_8:    case Builtin::BI__sync_lock_release_16: -    BuiltinIndex = 13; +    BuiltinIndex = 15;      NumFixed = 0;      ResultType = Context.VoidTy;      break; @@ -1557,7 +1799,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {    case Builtin::BI__sync_swap_4:    case Builtin::BI__sync_swap_8:    case Builtin::BI__sync_swap_16: -    BuiltinIndex = 14;  +    BuiltinIndex = 16;       break;    } @@ -1570,6 +1812,11 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {      return ExprError();    } +  if (WarnAboutSemanticsChange) { +    Diag(TheCall->getLocEnd(), diag::warn_sync_fetch_and_nand_semantics_change) +      << TheCall->getCallee()->getSourceRange(); +  } +    // Get the decl for the concrete builtin from this, we can tell what the    // concrete integer type we should convert to is.    unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; @@ -2031,7 +2278,46 @@ bool Sema::SemaBuiltinAssume(CallExpr *TheCall) {    if (Arg->HasSideEffects(Context))      return Diag(Arg->getLocStart(), diag::warn_assume_side_effects) -      << Arg->getSourceRange(); +      << Arg->getSourceRange() +      << cast<FunctionDecl>(TheCall->getCalleeDecl())->getIdentifier(); + +  return false; +} + +/// Handle __builtin_assume_aligned. This is declared +/// as (const void*, size_t, ...) and can take one optional constant int arg. +bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) { +  unsigned NumArgs = TheCall->getNumArgs(); + +  if (NumArgs > 3) +    return Diag(TheCall->getLocEnd(), +             diag::err_typecheck_call_too_many_args_at_most) +             << 0 /*function call*/ << 3 << NumArgs +             << TheCall->getSourceRange(); + +  // The alignment must be a constant integer. +  Expr *Arg = TheCall->getArg(1); + +  // We can't check the value of a dependent argument. +  if (!Arg->isTypeDependent() && !Arg->isValueDependent()) { +    llvm::APSInt Result; +    if (SemaBuiltinConstantArg(TheCall, 1, Result)) +      return true; + +    if (!Result.isPowerOf2()) +      return Diag(TheCall->getLocStart(), +                  diag::err_alignment_not_power_of_two) +           << Arg->getSourceRange(); +  } + +  if (NumArgs > 2) { +    ExprResult Arg(TheCall->getArg(2)); +    InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, +      Context.getSizeType(), false); +    Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); +    if (Arg.isInvalid()) return true; +    TheCall->setArg(2, Arg.get()); +  }    return false;  } @@ -3178,6 +3464,61 @@ static bool requiresParensToAddCast(const Expr *E) {    }  } +static std::pair<QualType, StringRef> +shouldNotPrintDirectly(const ASTContext &Context, +                       QualType IntendedTy, +                       const Expr *E) { +  // Use a 'while' to peel off layers of typedefs. +  QualType TyTy = IntendedTy; +  while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) { +    StringRef Name = UserTy->getDecl()->getName(); +    QualType CastTy = llvm::StringSwitch<QualType>(Name) +      .Case("NSInteger", Context.LongTy) +      .Case("NSUInteger", Context.UnsignedLongTy) +      .Case("SInt32", Context.IntTy) +      .Case("UInt32", Context.UnsignedIntTy) +      .Default(QualType()); + +    if (!CastTy.isNull()) +      return std::make_pair(CastTy, Name); + +    TyTy = UserTy->desugar(); +  } + +  // Strip parens if necessary. +  if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) +    return shouldNotPrintDirectly(Context, +                                  PE->getSubExpr()->getType(), +                                  PE->getSubExpr()); + +  // If this is a conditional expression, then its result type is constructed +  // via usual arithmetic conversions and thus there might be no necessary +  // typedef sugar there.  Recurse to operands to check for NSInteger & +  // Co. usage condition. +  if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { +    QualType TrueTy, FalseTy; +    StringRef TrueName, FalseName; + +    std::tie(TrueTy, TrueName) = +      shouldNotPrintDirectly(Context, +                             CO->getTrueExpr()->getType(), +                             CO->getTrueExpr()); +    std::tie(FalseTy, FalseName) = +      shouldNotPrintDirectly(Context, +                             CO->getFalseExpr()->getType(), +                             CO->getFalseExpr()); + +    if (TrueTy == FalseTy) +      return std::make_pair(TrueTy, TrueName); +    else if (TrueTy.isNull()) +      return std::make_pair(FalseTy, FalseName); +    else if (FalseTy.isNull()) +      return std::make_pair(TrueTy, TrueName); +  } + +  return std::make_pair(QualType(), StringRef()); +} +  bool  CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,                                      const char *StartSpecifier, @@ -3269,25 +3610,13 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,    // Special-case some of Darwin's platform-independence types by suggesting    // casts to primitive types that are known to be large enough. -  bool ShouldNotPrintDirectly = false; +  bool ShouldNotPrintDirectly = false; StringRef CastTyName;    if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { -    // Use a 'while' to peel off layers of typedefs. -    QualType TyTy = IntendedTy; -    while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) { -      StringRef Name = UserTy->getDecl()->getName(); -      QualType CastTy = llvm::StringSwitch<QualType>(Name) -        .Case("NSInteger", S.Context.LongTy) -        .Case("NSUInteger", S.Context.UnsignedLongTy) -        .Case("SInt32", S.Context.IntTy) -        .Case("UInt32", S.Context.UnsignedIntTy) -        .Default(QualType()); - -      if (!CastTy.isNull()) { -        ShouldNotPrintDirectly = true; -        IntendedTy = CastTy; -        break; -      } -      TyTy = UserTy->desugar(); +    QualType CastTy; +    std::tie(CastTy, CastTyName) = shouldNotPrintDirectly(S.Context, IntendedTy, E); +    if (!CastTy.isNull()) { +      IntendedTy = CastTy; +      ShouldNotPrintDirectly = true;      }    } @@ -3304,7 +3633,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,      CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen); -    if (IntendedTy == ExprTy) { +    if (IntendedTy == ExprTy && !ShouldNotPrintDirectly) {        // In this case, the specifier is wrong and should be changed to match        // the argument.        EmitFormatDiagnostic( @@ -3358,8 +3687,11 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,          // The expression has a type that should not be printed directly.          // We extract the name from the typedef because we don't want to show          // the underlying type in the diagnostic. -        StringRef Name = cast<TypedefType>(ExprTy)->getDecl()->getName(); - +        StringRef Name; +        if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(ExprTy)) +          Name = TypedefTy->getDecl()->getName(); +        else +          Name = CastTyName;          EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast)                                 << Name << IntendedTy << IsEnum                                 << E->getSourceRange(), @@ -3395,6 +3727,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,        break;      case Sema::VAK_Undefined: +    case Sema::VAK_MSVCUndefined:        EmitFormatDiagnostic(          S.PDiag(diag::warn_non_pod_vararg_with_format_string)            << S.getLangOpts().CPlusPlus11 @@ -3672,6 +4005,20 @@ void Sema::CheckFormatString(const StringLiteral *FExpr,    } // TODO: handle other formats  } +bool Sema::FormatStringHasSArg(const StringLiteral *FExpr) { +  // Str - The format string.  NOTE: this is NOT null-terminated! +  StringRef StrRef = FExpr->getString(); +  const char *Str = StrRef.data(); +  // Account for cases where the string literal is truncated in a declaration. +  const ConstantArrayType *T = Context.getAsConstantArrayType(FExpr->getType()); +  assert(T && "String literal not of constant array type!"); +  size_t TypeSize = T->getSize().getZExtValue(); +  size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size()); +  return analyze_format_string::ParseFormatStringHasSArg(Str, Str + StrLen, +                                                         getLangOpts(), +                                                         Context.getTargetInfo()); +} +  //===--- CHECK: Warn on use of wrong absolute value function. -------------===//  // Returns the related absolute value function that is larger, of 0 if one @@ -4346,7 +4693,8 @@ void Sema::CheckStrlcpycatArguments(const CallExpr *Call,                                      IdentifierInfo *FnName) {    // Don't crash if the user has the wrong number of arguments -  if (Call->getNumArgs() != 3) +  unsigned NumArgs = Call->getNumArgs(); +  if ((NumArgs != 3) && (NumArgs != 4))      return;    const Expr *SrcArg = ignoreLiteralAdditions(Call->getArg(1), Context); @@ -4628,7 +4976,7 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars,      DeclRefExpr *DR = cast<DeclRefExpr>(E);      // If we leave the immediate function, the lifetime isn't about to end. -    if (DR->refersToEnclosingLocal()) +    if (DR->refersToEnclosingVariableOrCapture())        return nullptr;      if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) @@ -4795,7 +5143,7 @@ do {      DeclRefExpr *DR = cast<DeclRefExpr>(E);      // If we leave the immediate function, the lifetime isn't about to end. -    if (DR->refersToEnclosingLocal()) +    if (DR->refersToEnclosingVariableOrCapture())        return nullptr;      if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) { @@ -5660,8 +6008,13 @@ static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) {  static void AnalyzeComparison(Sema &S, BinaryOperator *E) {    // The type the comparison is being performed in.    QualType T = E->getLHS()->getType(); -  assert(S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType()) -         && "comparison with mismatched types"); + +  // Only analyze comparison operators where both sides have been converted to +  // the same type. +  if (!S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType())) +    return AnalyzeImpConvsInComparison(S, E); + +  // Don't analyze value-dependent comparisons directly.    if (E->isValueDependent())      return AnalyzeImpConvsInComparison(S, E); @@ -5932,6 +6285,41 @@ void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall,    }  } +static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, +                                   SourceLocation CC) { +  if (S.Diags.isIgnored(diag::warn_impcast_null_pointer_to_integer, +                        E->getExprLoc())) +    return; + +  // Check for NULL (GNUNull) or nullptr (CXX11_nullptr). +  const Expr::NullPointerConstantKind NullKind = +      E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull); +  if (NullKind != Expr::NPCK_GNUNull && NullKind != Expr::NPCK_CXX11_nullptr) +    return; + +  // Return if target type is a safe conversion. +  if (T->isAnyPointerType() || T->isBlockPointerType() || +      T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType()) +    return; + +  SourceLocation Loc = E->getSourceRange().getBegin(); + +  // __null is usually wrapped in a macro.  Go up a macro if that is the case. +  if (NullKind == Expr::NPCK_GNUNull) { +    if (Loc.isMacroID()) +      Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first; +  } + +  // Only warn if the null and context location are in the same macro expansion. +  if (S.SourceMgr.getFileID(Loc) != S.SourceMgr.getFileID(CC)) +    return; + +  S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) +      << (NullKind == Expr::NPCK_CXX11_nullptr) << T << clang::SourceRange(CC) +      << FixItHint::CreateReplacement(Loc, +                                      S.getFixItZeroLiteralForType(T, Loc)); +} +  void CheckImplicitConversion(Sema &S, Expr *E, QualType T,                               SourceLocation CC, bool *ICContext = nullptr) {    if (E->isTypeDependent() || E->isValueDependent()) return; @@ -6074,19 +6462,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,      return;    } -  if ((E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) -           == Expr::NPCK_GNUNull) && !Target->isAnyPointerType() -      && !Target->isBlockPointerType() && !Target->isMemberPointerType() -      && Target->isScalarType() && !Target->isNullPtrType()) { -    SourceLocation Loc = E->getSourceRange().getBegin(); -    if (Loc.isMacroID()) -      Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first; -    if (!Loc.isMacroID() || CC.isMacroID()) -      S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) -          << T << clang::SourceRange(CC) -          << FixItHint::CreateReplacement(Loc, -                                          S.getFixItZeroLiteralForType(T, Loc)); -  } +  DiagnoseNullConversion(S, E, T, CC);    if (!Source->isIntegerType() || !Target->isIntegerType())      return; @@ -6196,7 +6572,7 @@ void CheckConditionalOperand(Sema &S, Expr *E, QualType T,  void CheckConditionalOperator(Sema &S, ConditionalOperator *E,                                SourceLocation CC, QualType T) { -  AnalyzeImplicitConversions(S, E->getCond(), CC); +  AnalyzeImplicitConversions(S, E->getCond(), E->getQuestionLoc());    bool Suspicious = false;    CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious); @@ -6222,6 +6598,14 @@ void CheckConditionalOperator(Sema &S, ConditionalOperator *E,                              E->getType(), CC, &Suspicious);  } +/// CheckBoolLikeConversion - Check conversion of given expression to boolean. +/// Input argument E is a logical expression. +static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) { +  if (S.getLangOpts().Bool) +    return; +  CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy, CC); +} +  /// AnalyzeImplicitConversions - Find and report any interesting  /// implicit conversions in the given expression.  There are a couple  /// of competing diagnostics here, -Wconversion and -Wsign-compare. @@ -6301,6 +6685,20 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) {        continue;      AnalyzeImplicitConversions(S, ChildExpr, CC);    } + +  if (BO && BO->isLogicalOp()) { +    Expr *SubExpr = BO->getLHS()->IgnoreParenImpCasts(); +    if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr)) +      ::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc()); + +    SubExpr = BO->getRHS()->IgnoreParenImpCasts(); +    if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr)) +      ::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc()); +  } + +  if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) +    if (U->getOpcode() == UO_LNot) +      ::CheckBoolLikeConversion(S, U->getSubExpr(), CC);  }  } // end anonymous namespace @@ -6343,6 +6741,22 @@ static bool CheckForReference(Sema &SemaRef, const Expr *E,    return true;  } +// Returns true if the SourceLocation is expanded from any macro body. +// Returns false if the SourceLocation is invalid, is from not in a macro +// expansion, or is from expanded from a top-level macro argument. +static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc) { +  if (Loc.isInvalid()) +    return false; + +  while (Loc.isMacroID()) { +    if (SM.isMacroBodyExpansion(Loc)) +      return true; +    Loc = SM.getImmediateMacroCallerLoc(Loc); +  } + +  return false; +} +  /// \brief Diagnose pointers that are always non-null.  /// \param E the expression containing the pointer  /// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is @@ -6356,8 +6770,12 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,      return;    // Don't warn inside macros. -  if (E->getExprLoc().isMacroID()) +  if (E->getExprLoc().isMacroID()) { +    const SourceManager &SM = getSourceManager(); +    if (IsInAnyMacroBody(SM, E->getExprLoc()) || +        IsInAnyMacroBody(SM, Range.getBegin()))        return; +  }    E = E->IgnoreImpCasts();    const bool IsCompare = NullKind != Expr::NPCK_NotNull; @@ -6400,7 +6818,40 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,    // Weak Decls can be null.    if (!D || D->isWeak())      return; - +   +  // Check for parameter decl with nonnull attribute +  if (const ParmVarDecl* PV = dyn_cast<ParmVarDecl>(D)) { +    if (getCurFunction() && !getCurFunction()->ModifiedNonNullParams.count(PV)) +      if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) { +        unsigned NumArgs = FD->getNumParams(); +        llvm::SmallBitVector AttrNonNull(NumArgs); +        for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) { +          if (!NonNull->args_size()) { +            AttrNonNull.set(0, NumArgs); +            break; +          } +          for (unsigned Val : NonNull->args()) { +            if (Val >= NumArgs) +              continue; +            AttrNonNull.set(Val); +          } +        } +        if (!AttrNonNull.empty()) +          for (unsigned i = 0; i < NumArgs; ++i) +            if (FD->getParamDecl(i) == PV && +                (AttrNonNull[i] || PV->hasAttr<NonNullAttr>())) { +              std::string Str; +              llvm::raw_string_ostream S(Str); +              E->printPretty(S, nullptr, getPrintingPolicy()); +              unsigned DiagID = IsCompare ? diag::warn_nonnull_parameter_compare +                                          : diag::warn_cast_nonnull_to_bool; +              Diag(E->getExprLoc(), DiagID) << S.str() << E->getSourceRange() +                << Range << IsEqual; +              return; +            } +      } +    } +      QualType T = D->getType();    const bool IsArray = T->isArrayType();    const bool IsFunction = T->isFunctionType(); @@ -6496,11 +6947,17 @@ void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) {    AnalyzeImplicitConversions(*this, E, CC);  } +/// CheckBoolLikeConversion - Check conversion of given expression to boolean. +/// Input argument E is a logical expression. +void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) { +  ::CheckBoolLikeConversion(*this, E, CC); +} +  /// Diagnose when expression is an integer constant expression and its evaluation  /// results in integer overflow  void Sema::CheckForIntOverflow (Expr *E) { -  if (isa<BinaryOperator>(E->IgnoreParens())) -    E->EvaluateForOverflow(Context); +  if (isa<BinaryOperator>(E->IgnoreParenCasts())) +    E->IgnoreParenCasts()->EvaluateForOverflow(Context);  }  namespace { @@ -6630,11 +7087,12 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {        Self.ModAsSideEffect = &ModAsSideEffect;      }      ~SequencedSubexpression() { -      for (unsigned I = 0, E = ModAsSideEffect.size(); I != E; ++I) { -        UsageInfo &U = Self.UsageMap[ModAsSideEffect[I].first]; -        U.Uses[UK_ModAsSideEffect] = ModAsSideEffect[I].second; -        Self.addUsage(U, ModAsSideEffect[I].first, -                      ModAsSideEffect[I].second.Use, UK_ModAsValue); +      for (auto MI = ModAsSideEffect.rbegin(), ME = ModAsSideEffect.rend(); +           MI != ME; ++MI) { +        UsageInfo &U = Self.UsageMap[MI->first]; +        auto &SideEffectUsage = U.Uses[UK_ModAsSideEffect]; +        Self.addUsage(U, MI->first, SideEffectUsage.Use, UK_ModAsValue); +        SideEffectUsage = MI->second;        }        Self.ModAsSideEffect = OldModAsSideEffect;      } @@ -7867,6 +8325,96 @@ void Sema::DiagnoseEmptyLoopBody(const Stmt *S,    }  } +//===--- CHECK: Warn on self move with std::move. -------------------------===// + +/// DiagnoseSelfMove - Emits a warning if a value is moved to itself. +void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, +                             SourceLocation OpLoc) { + +  if (Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc)) +    return; + +  if (!ActiveTemplateInstantiations.empty()) +    return; + +  // Strip parens and casts away. +  LHSExpr = LHSExpr->IgnoreParenImpCasts(); +  RHSExpr = RHSExpr->IgnoreParenImpCasts(); + +  // Check for a call expression +  const CallExpr *CE = dyn_cast<CallExpr>(RHSExpr); +  if (!CE || CE->getNumArgs() != 1) +    return; + +  // Check for a call to std::move +  const FunctionDecl *FD = CE->getDirectCallee(); +  if (!FD || !FD->isInStdNamespace() || !FD->getIdentifier() || +      !FD->getIdentifier()->isStr("move")) +    return; + +  // Get argument from std::move +  RHSExpr = CE->getArg(0); + +  const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr); +  const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr); + +  // Two DeclRefExpr's, check that the decls are the same. +  if (LHSDeclRef && RHSDeclRef) { +    if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl()) +      return; +    if (LHSDeclRef->getDecl()->getCanonicalDecl() != +        RHSDeclRef->getDecl()->getCanonicalDecl()) +      return; + +    Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() +                                        << LHSExpr->getSourceRange() +                                        << RHSExpr->getSourceRange(); +    return; +  } + +  // Member variables require a different approach to check for self moves. +  // MemberExpr's are the same if every nested MemberExpr refers to the same +  // Decl and that the base Expr's are DeclRefExpr's with the same Decl or +  // the base Expr's are CXXThisExpr's. +  const Expr *LHSBase = LHSExpr; +  const Expr *RHSBase = RHSExpr; +  const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr); +  const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr); +  if (!LHSME || !RHSME) +    return; + +  while (LHSME && RHSME) { +    if (LHSME->getMemberDecl()->getCanonicalDecl() != +        RHSME->getMemberDecl()->getCanonicalDecl()) +      return; + +    LHSBase = LHSME->getBase(); +    RHSBase = RHSME->getBase(); +    LHSME = dyn_cast<MemberExpr>(LHSBase); +    RHSME = dyn_cast<MemberExpr>(RHSBase); +  } + +  LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase); +  RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase); +  if (LHSDeclRef && RHSDeclRef) { +    if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl()) +      return; +    if (LHSDeclRef->getDecl()->getCanonicalDecl() != +        RHSDeclRef->getDecl()->getCanonicalDecl()) +      return; + +    Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() +                                        << LHSExpr->getSourceRange() +                                        << RHSExpr->getSourceRange(); +    return; +  } + +  if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase)) +    Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() +                                        << LHSExpr->getSourceRange() +                                        << RHSExpr->getSourceRange(); +} +  //===--- Layout compatibility ----------------------------------------------//  namespace { diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 3d250e3bef11..48bdd2a7d82c 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -292,7 +292,7 @@ namespace {      void MaybeAddResult(Result R, DeclContext *CurContext = nullptr);      /// \brief Add a new result to this result set, where we already know -    /// the hiding declation (if any). +    /// the hiding declaration (if any).      ///      /// \param R the result to add (if it is unique).      /// @@ -894,7 +894,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {    }    // Make sure that any given declaration only shows up in the result set once. -  if (!AllDeclsFound.insert(CanonDecl)) +  if (!AllDeclsFound.insert(CanonDecl).second)      return;    // If the filter is for nested-name-specifiers, then this result starts a @@ -957,7 +957,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,      return;    // Make sure that any given declaration only shows up in the result set once. -  if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl())) +  if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()).second)      return;    // If the filter is for nested-name-specifiers, then this result starts a @@ -2575,11 +2575,12 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,      const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);      assert(MD && "Not a macro?");      const MacroInfo *MI = MD->getMacroInfo(); +    assert((!MD->isDefined() || MI) && "missing MacroInfo for define");      Result.AddTypedTextChunk(                              Result.getAllocator().CopyString(Macro->getName())); -    if (!MI->isFunctionLike()) +    if (!MI || !MI->isFunctionLike())        return Result.TakeString();      // Format a function-like macro with placeholders for the arguments. @@ -3466,7 +3467,7 @@ static void AddObjCProperties(ObjCContainerDecl *Container,    // Add properties in this container.    for (const auto *P : Container->properties()) -    if (AddedProperties.insert(P->getIdentifier())) +    if (AddedProperties.insert(P->getIdentifier()).second)        Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr),                               CurContext); @@ -3477,7 +3478,7 @@ static void AddObjCProperties(ObjCContainerDecl *Container,      for (auto *M : Container->methods()) {        if (M->getSelector().isUnarySelector())          if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0)) -          if (AddedProperties.insert(Name)) { +          if (AddedProperties.insert(Name).second) {              CodeCompletionBuilder Builder(Results.getAllocator(),                                            Results.getCodeCompletionTUInfo());              AddResultTypeChunk(Context, Policy, M, Builder); @@ -4235,7 +4236,8 @@ void Sema::CodeCompleteConstructorInitializer(    bool SawLastInitializer = Initializers.empty();    CXXRecordDecl *ClassDecl = Constructor->getParent();    for (const auto &Base : ClassDecl->bases()) { -    if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))) { +    if (!InitializedBases.insert(Context.getCanonicalType(Base.getType())) +             .second) {        SawLastInitializer          = !Initializers.empty() &&             Initializers.back()->isBaseInitializer() && @@ -4258,7 +4260,8 @@ void Sema::CodeCompleteConstructorInitializer(    // Add completions for virtual base classes.    for (const auto &Base : ClassDecl->vbases()) { -    if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))) { +    if (!InitializedBases.insert(Context.getCanonicalType(Base.getType())) +             .second) {        SawLastInitializer          = !Initializers.empty() &&             Initializers.back()->isBaseInitializer() && @@ -4281,7 +4284,8 @@ void Sema::CodeCompleteConstructorInitializer(    // Add completions for members.    for (auto *Field : ClassDecl->fields()) { -    if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) { +    if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl())) +             .second) {        SawLastInitializer          = !Initializers.empty() &&             Initializers.back()->isAnyMemberInitializer() && @@ -4348,7 +4352,7 @@ void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,            Var->hasAttr<BlocksAttr>())          continue; -      if (Known.insert(Var->getIdentifier())) +      if (Known.insert(Var->getIdentifier()).second)          Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),                            CurContext, nullptr, false);      } @@ -4817,7 +4821,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container,        if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))          continue; -      if (!Selectors.insert(M->getSelector())) +      if (!Selectors.insert(M->getSelector()).second)          continue;        Result R = Result(M, Results.getBasePriority(M), nullptr); @@ -5400,13 +5404,13 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,                                         MEnd = SemaRef.MethodPool.end();           M != MEnd; ++M) {        for (ObjCMethodList *MethList = &M->second.second; -           MethList && MethList->Method;  +           MethList && MethList->getMethod();              MethList = MethList->getNext()) { -        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents)) +        if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))            continue; -        Result R(MethList->Method, Results.getBasePriority(MethList->Method), -                 nullptr); +        Result R(MethList->getMethod(), +                 Results.getBasePriority(MethList->getMethod()), nullptr);          R.StartParameter = SelIdents.size();          R.AllParametersAreInformative = false;          Results.MaybeAddResult(R, SemaRef.CurContext); @@ -5573,16 +5577,16 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,                                      MEnd = MethodPool.end();           M != MEnd; ++M) {        for (ObjCMethodList *MethList = &M->second.first; -           MethList && MethList->Method;  +           MethList && MethList->getMethod();              MethList = MethList->getNext()) { -        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents)) +        if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))            continue; -        if (!Selectors.insert(MethList->Method->getSelector())) +        if (!Selectors.insert(MethList->getMethod()->getSelector()).second)            continue; -        Result R(MethList->Method, Results.getBasePriority(MethList->Method), -                 nullptr); +        Result R(MethList->getMethod(), +                 Results.getBasePriority(MethList->getMethod()), nullptr);          R.StartParameter = SelIdents.size();          R.AllParametersAreInformative = false;          Results.MaybeAddResult(R, CurContext); @@ -5858,7 +5862,7 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,    TranslationUnitDecl *TU = Context.getTranslationUnitDecl();    for (const auto *D : TU->decls())       if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D)) -      if (CategoryNames.insert(Category->getIdentifier())) +      if (CategoryNames.insert(Category->getIdentifier()).second)          Results.AddResult(Result(Category, Results.getBasePriority(Category),                                   nullptr),                            CurContext, nullptr, false); @@ -5896,7 +5900,7 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S,    while (Class) {      for (const auto *Cat : Class->visible_categories()) {        if ((!IgnoreImplemented || !Cat->getImplementation()) && -          CategoryNames.insert(Cat->getIdentifier())) +          CategoryNames.insert(Cat->getIdentifier()).second)          Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr),                            CurContext, nullptr, false);      } @@ -6217,7 +6221,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,    // Add the normal accessor -(type)key.    if (IsInstanceMethod && -      KnownSelectors.insert(Selectors.getNullarySelector(PropName)) && +      KnownSelectors.insert(Selectors.getNullarySelector(PropName)).second &&        ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {      if (ReturnType.isNull())        AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, @@ -6238,7 +6242,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,           Property->getType()->isBooleanType())))) {      std::string SelectorName = (Twine("is") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) +            .second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("BOOL"); @@ -6257,7 +6262,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        !Property->getSetterMethodDecl()) {      std::string SelectorName = (Twine("set") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6309,7 +6314,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        (ReturnType.isNull() || ReturnType->isIntegerType())) {      std::string SelectorName = (Twine("countOf") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) +            .second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("NSUInteger"); @@ -6332,7 +6338,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName        = (Twine("objectIn") + UpperKey + "AtIndex").str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("id"); @@ -6359,7 +6365,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName        = (Twine(Property->getName()) + "AtIndexes").str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("NSArray *"); @@ -6384,7 +6390,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        &Context.Idents.get("range")      }; -    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { +    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6418,7 +6424,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        &Context.Idents.get(SelectorName)      }; -    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { +    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6450,7 +6456,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        &Context.Idents.get("atIndexes")      }; -    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { +    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6478,7 +6484,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName        = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);         -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6500,7 +6506,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName        = (Twine("remove") + UpperKey + "AtIndexes").str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);         -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6526,7 +6532,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        &Context.Idents.get("withObject")      }; -    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { +    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6559,7 +6565,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        &Context.Idents.get(SelectorName2)      }; -    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { +    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6592,7 +6598,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,            ->getName() == "NSEnumerator"))) {      std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) +            .second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("NSEnumerator *"); @@ -6610,7 +6617,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,        (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {      std::string SelectorName = (Twine("memberOf") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddPlaceholderChunk("object-type"); @@ -6641,7 +6648,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName        = (Twine("add") + UpperKey + Twine("Object")).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6663,7 +6670,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,    if (IsInstanceMethod && ReturnTypeMatchesVoid) {      std::string SelectorName = (Twine("add") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6685,7 +6692,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName        = (Twine("remove") + UpperKey + Twine("Object")).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6707,7 +6714,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,    if (IsInstanceMethod && ReturnTypeMatchesVoid) {      std::string SelectorName = (Twine("remove") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6728,7 +6735,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,    if (IsInstanceMethod && ReturnTypeMatchesVoid) {      std::string SelectorName = (Twine("intersect") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("void"); @@ -6756,7 +6763,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName         = (Twine("keyPathsForValuesAffecting") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) +            .second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("NSSet *"); @@ -6777,7 +6785,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,      std::string SelectorName         = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();      IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); -    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { +    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) +            .second) {        if (ReturnType.isNull()) {          Builder.AddChunk(CodeCompletionString::CK_LeftParen);          Builder.AddTextChunk("BOOL"); @@ -6985,16 +6994,18 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,         M != MEnd; ++M) {      for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :                                                         &M->second.second; -         MethList && MethList->Method;  +         MethList && MethList->getMethod();            MethList = MethList->getNext()) { -      if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents)) +      if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))          continue;        if (AtParameterName) {          // Suggest parameter names we've seen before.          unsigned NumSelIdents = SelIdents.size(); -        if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) { -          ParmVarDecl *Param = MethList->Method->parameters()[NumSelIdents-1]; +        if (NumSelIdents && +            NumSelIdents <= MethList->getMethod()->param_size()) { +          ParmVarDecl *Param = +              MethList->getMethod()->parameters()[NumSelIdents - 1];            if (Param->getIdentifier()) {              CodeCompletionBuilder Builder(Results.getAllocator(),                                            Results.getCodeCompletionTUInfo()); @@ -7007,8 +7018,8 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,          continue;        } -      Result R(MethList->Method, Results.getBasePriority(MethList->Method), -               nullptr); +      Result R(MethList->getMethod(), +               Results.getBasePriority(MethList->getMethod()), nullptr);        R.StartParameter = SelIdents.size();        R.AllParametersAreInformative = false;        R.DeclaringEntity = true; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 87162273bbe6..007470344f19 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -152,7 +152,10 @@ static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,      auto *TD = TST->getTemplateName().getAsTemplateDecl();      if (!TD)        continue; -    auto *BasePrimaryTemplate = cast<CXXRecordDecl>(TD->getTemplatedDecl()); +    auto *BasePrimaryTemplate = +        dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl()); +    if (!BasePrimaryTemplate) +      continue;      // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly      // by calling or integrating with the main LookupQualifiedName mechanism.      for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) { @@ -283,10 +286,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,    case LookupResult::NotFound:    case LookupResult::NotFoundInCurrentInstantiation:      if (CorrectedII) { -      TypeNameValidatorCCC Validator(true, isClassName); -      TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), -                                              Kind, S, SS, Validator, -                                              CTK_ErrorRecovery); +      TypoCorrection Correction = CorrectTypo( +          Result.getLookupNameInfo(), Kind, S, SS, +          llvm::make_unique<TypeNameValidatorCCC>(true, isClassName), +          CTK_ErrorRecovery);        IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();        TemplateTy Template;        bool MemberOfUnknownSpecialization; @@ -377,6 +380,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,      DiagnoseUseOfDecl(IIDecl, NameLoc);      T = Context.getTypeDeclType(TD); +    MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);      // NOTE: avoid constructing an ElaboratedType(Loc) if this is a      // constructor or destructor name (in such a case, the scope specifier @@ -494,6 +498,9 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {  /// @endcode  bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S) {    if (CurContext->isRecord()) { +    if (SS->getScopeRep()->getKind() == NestedNameSpecifier::Super) +      return true; +      const Type *Ty = SS->getScopeRep()->getAsType();      CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext); @@ -516,10 +523,11 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,    // There may have been a typo in the name of the type. Look up typo    // results, in case we have something that we can suggest. -  TypeNameValidatorCCC Validator(false, false, AllowClassTemplates); -  if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), -                                             LookupOrdinaryName, S, SS, -                                             Validator, CTK_ErrorRecovery)) { +  if (TypoCorrection Corrected = +          CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS, +                      llvm::make_unique<TypeNameValidatorCCC>( +                          false, false, AllowClassTemplates), +                      CTK_ErrorRecovery)) {      if (Corrected.isKeyword()) {        // We corrected to a keyword.        diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II); @@ -679,13 +687,11 @@ static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS,    return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));  } -Sema::NameClassification Sema::ClassifyName(Scope *S, -                                            CXXScopeSpec &SS, -                                            IdentifierInfo *&Name, -                                            SourceLocation NameLoc, -                                            const Token &NextToken, -                                            bool IsAddressOfOperand, -                                            CorrectionCandidateCallback *CCC) { +Sema::NameClassification +Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, +                   SourceLocation NameLoc, const Token &NextToken, +                   bool IsAddressOfOperand, +                   std::unique_ptr<CorrectionCandidateCallback> CCC) {    DeclarationNameInfo NameInfo(Name, NameLoc);    ObjCMethodDecl *CurMethod = getCurMethodDecl(); @@ -762,7 +768,7 @@ Corrected:        SecondTry = true;        if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),                                                   Result.getLookupKind(), S,  -                                                 &SS, *CCC, +                                                 &SS, std::move(CCC),                                                   CTK_ErrorRecovery)) {          unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;          unsigned QualifiedDiag = diag::err_no_member_suggest; @@ -925,6 +931,7 @@ Corrected:    NamedDecl *FirstDecl = (*Result.begin())->getUnderlyingDecl();    if (TypeDecl *Type = dyn_cast<TypeDecl>(FirstDecl)) {      DiagnoseUseOfDecl(Type, NameLoc); +    MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);      QualType T = Context.getTypeDeclType(Type);      if (SS.isNotEmpty())        return buildNestedType(*this, SS, T, NameLoc); @@ -1392,10 +1399,22 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {    if (isa<LabelDecl>(D))      return true; + +  // Except for labels, we only care about unused decls that are local to +  // functions. +  bool WithinFunction = D->getDeclContext()->isFunctionOrMethod(); +  if (const auto *R = dyn_cast<CXXRecordDecl>(D->getDeclContext())) +    // For dependent types, the diagnostic is deferred. +    WithinFunction = +        WithinFunction || (R->isLocalClass() && !R->isDependentType()); +  if (!WithinFunction) +    return false; + +  if (isa<TypedefNameDecl>(D)) +    return true;    // White-list anything that isn't a local variable. -  if (!isa<VarDecl>(D) || isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) || -      !D->getDeclContext()->isFunctionOrMethod()) +  if (!isa<VarDecl>(D) || isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D))      return false;    // Types of valid local variables should be complete, so this should succeed. @@ -1458,11 +1477,30 @@ static void GenerateFixForUnusedDecl(const NamedDecl *D, ASTContext &Ctx,    return;  } +void Sema::DiagnoseUnusedNestedTypedefs(const RecordDecl *D) { +  if (D->getTypeForDecl()->isDependentType()) +    return; + +  for (auto *TmpD : D->decls()) { +    if (const auto *T = dyn_cast<TypedefNameDecl>(TmpD)) +      DiagnoseUnusedDecl(T); +    else if(const auto *R = dyn_cast<RecordDecl>(TmpD)) +      DiagnoseUnusedNestedTypedefs(R); +  } +} +  /// DiagnoseUnusedDecl - Emit warnings about declarations that are not used  /// unless they are marked attr(unused).  void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {    if (!ShouldDiagnoseUnusedDecl(D))      return; + +  if (auto *TD = dyn_cast<TypedefNameDecl>(D)) { +    // typedefs can be referenced later on, so the diagnostics are emitted +    // at end-of-translation-unit. +    UnusedLocalTypedefNameCandidates.insert(TD); +    return; +  }    FixItHint Hint;    GenerateFixForUnusedDecl(D, Context, Hint); @@ -1481,8 +1519,14 @@ void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {  static void CheckPoppedLabel(LabelDecl *L, Sema &S) {    // Verify that we have no forward references left.  If so, there was a goto    // or address of a label taken, but no definition of it.  Label fwd -  // definitions are indicated with a null substmt. -  if (L->getStmt() == nullptr) +  // definitions are indicated with a null substmt which is also not a resolved +  // MS inline assembly label name. +  bool Diagnose = false; +  if (L->isMSAsmLabel()) +    Diagnose = !L->isResolvedMSAsmLabel(); +  else +    Diagnose = L->getStmt() == nullptr; +  if (Diagnose)      S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName();  } @@ -1502,8 +1546,11 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {      if (!D->getDeclName()) continue;      // Diagnose unused variables in this scope. -    if (!S->hasUnrecoverableErrorOccurred()) +    if (!S->hasUnrecoverableErrorOccurred()) {        DiagnoseUnusedDecl(D); +      if (const auto *RD = dyn_cast<RecordDecl>(D)) +        DiagnoseUnusedNestedTypedefs(RD); +    }      // If this was a forward reference to a label, verify it was defined.      if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) @@ -1537,10 +1584,10 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,    if (!IDecl && DoTypoCorrection) {      // Perform typo correction at the given location, but only if we      // find an Objective-C class name. -    DeclFilterCCC<ObjCInterfaceDecl> Validator; -    if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), -                                       LookupOrdinaryName, TUScope, nullptr, -                                       Validator, CTK_ErrorRecovery)) { +    if (TypoCorrection C = CorrectTypo( +            DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, nullptr, +            llvm::make_unique<DeclFilterCCC<ObjCInterfaceDecl>>(), +            CTK_ErrorRecovery)) {        diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id);        IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>();        Id = IDecl->getIdentifier(); @@ -1620,32 +1667,30 @@ static StringRef getHeaderName(ASTContext::GetBuiltinTypeError Error) {  /// file scope.  lazily create a decl for it. ForRedeclaration is true  /// if we're creating this built-in in anticipation of redeclaring the  /// built-in. -NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, +NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,                                       Scope *S, bool ForRedeclaration,                                       SourceLocation Loc) {    LookupPredefedObjCSuperType(*this, S, II); -   -  Builtin::ID BID = (Builtin::ID)bid;    ASTContext::GetBuiltinTypeError Error; -  QualType R = Context.GetBuiltinType(BID, Error); +  QualType R = Context.GetBuiltinType(ID, Error);    if (Error) {      if (ForRedeclaration)        Diag(Loc, diag::warn_implicit_decl_requires_sysheader)            << getHeaderName(Error) -          << Context.BuiltinInfo.GetName(BID); +          << Context.BuiltinInfo.GetName(ID);      return nullptr;    } -  if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) { +  if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(ID)) {      Diag(Loc, diag::ext_implicit_lib_function_decl) -      << Context.BuiltinInfo.GetName(BID) +      << Context.BuiltinInfo.GetName(ID)        << R; -    if (Context.BuiltinInfo.getHeaderName(BID) && +    if (Context.BuiltinInfo.getHeaderName(ID) &&          !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc))        Diag(Loc, diag::note_include_header_or_declare) -          << Context.BuiltinInfo.getHeaderName(BID) -          << Context.BuiltinInfo.GetName(BID); +          << Context.BuiltinInfo.getHeaderName(ID) +          << Context.BuiltinInfo.GetName(ID);    }    DeclContext *Parent = Context.getTranslationUnitDecl(); @@ -1725,6 +1770,43 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,    filter.done();  } +/// Typedef declarations don't have linkage, but they still denote the same +/// entity if their types are the same. +/// FIXME: This is notionally doing the same thing as ASTReaderDecl's +/// isSameEntity. +static void filterNonConflictingPreviousTypedefDecls(ASTContext &Context, +                                                     TypedefNameDecl *Decl, +                                                     LookupResult &Previous) { +  // This is only interesting when modules are enabled. +  if (!Context.getLangOpts().Modules) +    return; + +  // Empty sets are uninteresting. +  if (Previous.empty()) +    return; + +  LookupResult::Filter Filter = Previous.makeFilter(); +  while (Filter.hasNext()) { +    NamedDecl *Old = Filter.next(); + +    // Non-hidden declarations are never ignored. +    if (!Old->isHidden()) +      continue; + +    // Declarations of the same entity are not ignored, even if they have +    // different linkages. +    if (auto *OldTD = dyn_cast<TypedefNameDecl>(Old)) +      if (Context.hasSameType(OldTD->getUnderlyingType(), +                              Decl->getUnderlyingType())) +        continue; + +    if (!Old->isExternallyVisible()) +      Filter.erase(); +  } + +  Filter.done(); +} +  bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {    QualType OldType;    if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) @@ -2072,6 +2154,14 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,      NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(),                                         AttrSpellingListIndex,                                         IA->getSemanticSpelling()); +  else if (const auto *AA = dyn_cast<AlwaysInlineAttr>(Attr)) +    NewAttr = S.mergeAlwaysInlineAttr(D, AA->getRange(), +                                      &S.Context.Idents.get(AA->getSpelling()), +                                      AttrSpellingListIndex); +  else if (const auto *MA = dyn_cast<MinSizeAttr>(Attr)) +    NewAttr = S.mergeMinSizeAttr(D, MA->getRange(), AttrSpellingListIndex); +  else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr)) +    NewAttr = S.mergeOptimizeNoneAttr(D, OA->getRange(), AttrSpellingListIndex);    else if (isa<AlignedAttr>(Attr))      // AlignedAttrs are handled separately, because we need to handle all      // such attributes on a declaration at the same time. @@ -3149,8 +3239,15 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {    }    // Merge the types. -  MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous)); +  VarDecl *MostRecent = Old->getMostRecentDecl(); +  if (MostRecent != Old) { +    MergeVarDeclTypes(New, MostRecent, +                      mergeTypeWithPrevious(*this, New, MostRecent, Previous)); +    if (New->isInvalidDecl()) +      return; +  } +  MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous));    if (New->isInvalidDecl())      return; @@ -3195,12 +3292,12 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {    // Check if extern is followed by non-extern and vice-versa.    if (New->hasExternalStorage() && -      !Old->hasLinkage() && Old->isLocalVarDecl()) { +      !Old->hasLinkage() && Old->isLocalVarDeclOrParm()) {      Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();      Diag(OldLocation, PrevDiag);      return New->setInvalidDecl();    } -  if (Old->hasLinkage() && New->isLocalVarDecl() && +  if (Old->hasLinkage() && New->isLocalVarDeclOrParm() &&        !New->hasExternalStorage()) {      Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();      Diag(OldLocation, PrevDiag); @@ -3407,21 +3504,39 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,      }    } -  // Check for Microsoft C extension: anonymous struct member. -  if (getLangOpts().MicrosoftExt && !getLangOpts().CPlusPlus && -      CurContext->isRecord() && +  // C11 6.7.2.1p2: +  //   A struct-declaration that does not declare an anonymous structure or +  //   anonymous union shall contain a struct-declarator-list. +  // +  // This rule also existed in C89 and C99; the grammar for struct-declaration +  // did not permit a struct-declaration without a struct-declarator-list. +  if (!getLangOpts().CPlusPlus && CurContext->isRecord() &&        DS.getStorageClassSpec() == DeclSpec::SCS_unspecified) { -    // Handle 2 kinds of anonymous struct: +    // Check for Microsoft C extension: anonymous struct/union member. +    // Handle 2 kinds of anonymous struct/union:      //   struct STRUCT; +    //   union UNION;      // and      //   STRUCT_TYPE;  <- where STRUCT_TYPE is a typedef struct. -    RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag); -    if ((Record && Record->getDeclName() && !Record->isCompleteDefinition()) || -        (DS.getTypeSpecType() == DeclSpec::TST_typename && -         DS.getRepAsType().get()->isStructureType())) { -      Diag(DS.getLocStart(), diag::ext_ms_anonymous_struct) -        << DS.getSourceRange(); -      return BuildMicrosoftCAnonymousStruct(S, DS, Record); +    //   UNION_TYPE;   <- where UNION_TYPE is a typedef union. +    if ((Tag && Tag->getDeclName()) || +        DS.getTypeSpecType() == DeclSpec::TST_typename) { +      RecordDecl *Record = nullptr; +      if (Tag) +        Record = dyn_cast<RecordDecl>(Tag); +      else if (const RecordType *RT = +                   DS.getRepAsType().get()->getAsStructureType()) +        Record = RT->getDecl(); +      else if (const RecordType *UT = DS.getRepAsType().get()->getAsUnionType()) +        Record = UT->getDecl(); + +      if (Record && getLangOpts().MicrosoftExt) { +        Diag(DS.getLocStart(), diag::ext_ms_anonymous_record) +          << Record->isUnion() << DS.getSourceRange(); +        return BuildMicrosoftCAnonymousStruct(S, DS, Record); +      } + +      DeclaresAnything = false;      }    } @@ -3622,10 +3737,12 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,          for (unsigned i = 0; i < Chaining.size(); i++)            NamedChain[i] = Chaining[i]; -        IndirectFieldDecl* IndirectField = -          IndirectFieldDecl::Create(SemaRef.Context, Owner, VD->getLocation(), -                                    VD->getIdentifier(), VD->getType(), -                                    NamedChain, Chaining.size()); +        IndirectFieldDecl *IndirectField = IndirectFieldDecl::Create( +            SemaRef.Context, Owner, VD->getLocation(), VD->getIdentifier(), +            VD->getType(), NamedChain, Chaining.size()); + +        for (const auto *Attr : VD->attrs()) +          IndirectField->addAttr(Attr->clone(SemaRef.Context));          IndirectField->setAccess(AS);          IndirectField->setImplicit(); @@ -3893,7 +4010,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,        FieldCollector->Add(cast<FieldDecl>(Anon));    } else {      DeclSpec::SCS SCSpec = DS.getStorageClassSpec(); -    VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(DS); +    StorageClass SC = StorageClassSpecToVarDeclStorageClass(DS);      if (SCSpec == DeclSpec::SCS_mutable) {        // mutable can only appear on non-static class members, so it's always        // an error here @@ -3962,28 +4079,28 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,  ///  /// void foo() {  ///   B var; -///   var.a = 3;  +///   var.a = 3;  /// }  ///  Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,                                             RecordDecl *Record) { -   -  // If there is no Record, get the record via the typedef. -  if (!Record) -    Record = DS.getRepAsType().get()->getAsStructureType()->getDecl(); +  assert(Record && "expected a record!");    // Mock up a declarator.    Declarator Dc(DS, Declarator::TypeNameContext);    TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);    assert(TInfo && "couldn't build declarator info for anonymous struct"); +  auto *ParentDecl = cast<RecordDecl>(CurContext); +  QualType RecTy = Context.getTypeDeclType(Record); +    // Create a declaration for this anonymous struct.    NamedDecl *Anon = FieldDecl::Create(Context, -                             cast<RecordDecl>(CurContext), +                             ParentDecl,                               DS.getLocStart(),                               DS.getLocStart(),                               /*IdentifierInfo=*/nullptr, -                             Context.getTypeDeclType(Record), +                             RecTy,                               TInfo,                               /*BitWidth=*/nullptr, /*Mutable=*/false,                               /*InitStyle=*/ICIS_NoInit); @@ -3999,10 +4116,13 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,    Chain.push_back(Anon);    RecordDecl *RecordDef = Record->getDefinition(); -  if (!RecordDef || InjectAnonymousStructOrUnionMembers(*this, S, CurContext, -                                                        RecordDef, AS_none, -                                                        Chain, true)) +  if (RequireCompleteType(Anon->getLocation(), RecTy, +                          diag::err_field_incomplete) || +      InjectAnonymousStructOrUnionMembers(*this, S, CurContext, RecordDef, +                                          AS_none, Chain, true)) {      Anon->setInvalidDecl(); +    ParentDecl->setInvalidDecl(); +  }    return Anon;  } @@ -4835,7 +4955,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,    // in an outer scope, it isn't the same thing.    FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false,                         /*AllowInlineNamespace*/false); -  filterNonConflictingPreviousDecls(Context, NewTD, Previous); +  filterNonConflictingPreviousTypedefDecls(Context, NewTD, Previous);    if (!Previous.empty()) {      Redeclaration = true;      MergeTypedefNameDecl(NewTD, Previous); @@ -4995,14 +5115,7 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {    }    // dll attributes require external linkage. -  if (const DLLImportAttr *Attr = ND.getAttr<DLLImportAttr>()) { -    if (!ND.isExternallyVisible()) { -      S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern) -        << &ND << Attr; -      ND.setInvalidDecl(); -    } -  } -  if (const DLLExportAttr *Attr = ND.getAttr<DLLExportAttr>()) { +  if (const InheritableAttr *Attr = getDLLAttr(&ND)) {      if (!ND.isExternallyVisible()) {        S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)          << &ND << Attr; @@ -5064,17 +5177,22 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,    }    // A redeclaration is not allowed to drop a dllimport attribute, the only -  // exception being inline function definitions. +  // exceptions being inline function definitions, local extern declarations, +  // and qualified friend declarations.    // NB: MSVC converts such a declaration to dllexport. -  bool IsInline = false, IsStaticDataMember = false; +  bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;    if (const auto *VD = dyn_cast<VarDecl>(NewDecl))      // Ignore static data because out-of-line definitions are diagnosed      // separately.      IsStaticDataMember = VD->isStaticDataMember(); -  else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl)) +  else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl)) {      IsInline = FD->isInlined(); +    IsQualifiedFriend = FD->getQualifier() && +                        FD->getFriendObjectKind() == Decl::FOK_Declared; +  } -  if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) { +  if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember && +      !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {      S.Diag(NewDecl->getLocation(),             diag::warn_redeclaration_without_attribute_prev_attribute_ignored)        << NewDecl << OldImportAttr; @@ -5082,6 +5200,14 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,      S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);      OldDecl->dropAttr<DLLImportAttr>();      NewDecl->dropAttr<DLLImportAttr>(); +  } else if (IsInline && OldImportAttr && +             !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { +    // In MinGW, seeing a function declared inline drops the dllimport attribute. +    OldDecl->dropAttr<DLLImportAttr>(); +    NewDecl->dropAttr<DLLImportAttr>(); +    S.Diag(NewDecl->getLocation(), +           diag::warn_dllimport_dropped_from_inline_function) +        << NewDecl << OldImportAttr;    }  } @@ -5222,8 +5348,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,    DeclarationName Name = GetNameForDeclarator(D).getName();    DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); -  VarDecl::StorageClass SC = -    StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); +  StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());    // dllimport globals without explicit storage class are treated as extern. We    // have to change the storage class this early to get the right DeclContext. @@ -5434,7 +5559,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,            // Only C++1y supports variable templates (N3651).            Diag(D.getIdentifierLoc(), -               getLangOpts().CPlusPlus1y +               getLangOpts().CPlusPlus14                     ? diag::warn_cxx11_compat_variable_template                     : diag::ext_variable_template);          } @@ -5503,22 +5628,20 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,      NewVD->setLocalExternDecl();    if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) { -    if (NewVD->hasLocalStorage()) { -      // C++11 [dcl.stc]p4: -      //   When thread_local is applied to a variable of block scope the -      //   storage-class-specifier static is implied if it does not appear -      //   explicitly. -      // Core issue: 'static' is not implied if the variable is declared -      //   'extern'. -      if (SCSpec == DeclSpec::SCS_unspecified && -          TSCS == DeclSpec::TSCS_thread_local && -          DC->isFunctionOrMethod()) -        NewVD->setTSCSpec(TSCS); -      else -        Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), -             diag::err_thread_non_global) -          << DeclSpec::getSpecifierName(TSCS); -    } else if (!Context.getTargetInfo().isTLSSupported()) +    // C++11 [dcl.stc]p4: +    //   When thread_local is applied to a variable of block scope the +    //   storage-class-specifier static is implied if it does not appear +    //   explicitly. +    // Core issue: 'static' is not implied if the variable is declared +    //   'extern'. +    if (NewVD->hasLocalStorage() && +        (SCSpec != DeclSpec::SCS_unspecified || +         TSCS != DeclSpec::TSCS_thread_local || +         !DC->isFunctionOrMethod())) +      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), +           diag::err_thread_non_global) +        << DeclSpec::getSpecifierName(TSCS); +    else if (!Context.getTargetInfo().isTLSSupported())        Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),             diag::err_thread_unsupported);      else @@ -6198,7 +6321,7 @@ static void ReportOverrides(Sema& S, unsigned DiagID, const CXXMethodDecl *MD,  /// AddOverriddenMethods - See if a method overrides any in the base classes,  /// and if so, check that it's a valid override and remember it.  bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { -  // Look for virtual methods in base classes that this method might override. +  // Look for methods in base classes that this method might override.    CXXBasePaths Paths;    FindOverriddenMethodData Data;    Data.Method = MD; @@ -6320,8 +6443,6 @@ static NamedDecl *DiagnoseInvalidRedeclaration(    assert(!Prev.isAmbiguous() &&           "Cannot have an ambiguity in previous-declaration lookup");    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); -  DifferentNameValidatorCCC Validator(SemaRef.Context, NewFD, -                                      MD ? MD->getParent() : nullptr);    if (!Prev.empty()) {      for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();           Func != FuncEnd; ++Func) { @@ -6337,9 +6458,11 @@ static NamedDecl *DiagnoseInvalidRedeclaration(      }    // If the qualified name lookup yielded nothing, try typo correction    } else if ((Correction = SemaRef.CorrectTypo( -                 Prev.getLookupNameInfo(), Prev.getLookupKind(), S, -                 &ExtraArgs.D.getCXXScopeSpec(), Validator, -                 Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) { +                  Prev.getLookupNameInfo(), Prev.getLookupKind(), S, +                  &ExtraArgs.D.getCXXScopeSpec(), +                  llvm::make_unique<DifferentNameValidatorCCC>( +                      SemaRef.Context, NewFD, MD ? MD->getParent() : nullptr), +                  Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) {      // Set up everything for the call to ActOnFunctionDeclarator      ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(),                                ExtraArgs.D.getIdentifierLoc()); @@ -6436,8 +6559,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration(    return nullptr;  } -static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef,  -                                                          Declarator &D) { +static StorageClass getFunctionStorageClass(Sema &SemaRef, Declarator &D) {    switch (D.getDeclSpec().getStorageClassSpec()) {    default: llvm_unreachable("Unknown storage class!");    case DeclSpec::SCS_auto: @@ -6475,7 +6597,7 @@ static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef,  static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,                                             DeclContext *DC, QualType &R,                                             TypeSourceInfo *TInfo, -                                           FunctionDecl::StorageClass SC, +                                           StorageClass SC,                                             bool &IsVirtualOkay) {    DeclarationNameInfo NameInfo = SemaRef.GetNameForDeclarator(D);    DeclarationName Name = NameInfo.getName(); @@ -6500,9 +6622,6 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,      if (D.isInvalidType())        NewFD->setInvalidDecl(); -    // Set the lexical context. -    NewFD->setLexicalDeclContext(SemaRef.CurContext); -      return NewFD;    } @@ -6602,6 +6721,11 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,      IsVirtualOkay = !Ret->isStatic();      return Ret;    } else { +    bool isFriend = +        SemaRef.getLangOpts().CPlusPlus && D.getDeclSpec().isFriendSpecified(); +    if (!isFriend && SemaRef.CurContext->isRecord()) +      return nullptr; +      // Determine whether the function was written with a      // prototype. This true when:      //   - we're in C++ (where every function has a prototype), @@ -6655,7 +6779,7 @@ static void checkIsValidOpenCLKernelParameter(    Sema &S,    Declarator &D,    ParmVarDecl *Param, -  llvm::SmallPtrSet<const Type *, 16> &ValidTypes) { +  llvm::SmallPtrSetImpl<const Type *> &ValidTypes) {    QualType PT = Param->getType();    // Cache the valid types we encounter to avoid rechecking structs that are @@ -6802,7 +6926,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,    // TODO: consider using NameInfo for diagnostic.    DeclarationNameInfo NameInfo = GetNameForDeclarator(D);    DeclarationName Name = NameInfo.getName(); -  FunctionDecl::StorageClass SC = getFunctionStorageClass(*this, D); +  StorageClass SC = getFunctionStorageClass(*this, D);    if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), @@ -6990,12 +7114,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,          NewFD->setVirtualAsWritten(true);        } -      if (getLangOpts().CPlusPlus1y && +      if (getLangOpts().CPlusPlus14 &&            NewFD->getReturnType()->isUndeducedType())          Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual);      } -    if (getLangOpts().CPlusPlus1y && +    if (getLangOpts().CPlusPlus14 &&          (NewFD->isDependentContext() ||           (isFriend && CurContext->isDependentContext())) &&          NewFD->getReturnType()->isUndeducedType()) { @@ -7126,12 +7250,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,      const FunctionProtoType *FPT = R->getAs<FunctionProtoType>();      if ((Name.getCXXOverloadedOperator() == OO_Delete ||           Name.getCXXOverloadedOperator() == OO_Array_Delete) && -        getLangOpts().CPlusPlus11 && FPT && !FPT->hasExceptionSpec()) { -      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); -      EPI.ExceptionSpecType = EST_BasicNoexcept; -      NewFD->setType(Context.getFunctionType(FPT->getReturnType(), -                                             FPT->getParamTypes(), EPI)); -    } +        getLangOpts().CPlusPlus11 && FPT && !FPT->hasExceptionSpec()) +      NewFD->setType(Context.getFunctionType( +          FPT->getReturnType(), FPT->getParamTypes(), +          FPT->getExtProtoInfo().withExceptionSpec(EST_BasicNoexcept)));    }    // Filter out previous declarations that don't match the scope. @@ -7232,7 +7354,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,                                      CodeSegStack.CurrentValue->getString(),                                      CodeSegStack.CurrentPragmaLocation));      if (UnifySection(CodeSegStack.CurrentValue->getString(), -                     PSF_Implicit | PSF_Execute | PSF_Read, NewFD)) +                     ASTContext::PSF_Implicit | ASTContext::PSF_Execute | +                         ASTContext::PSF_Read, +                     NewFD))        NewFD->dropAttr<SectionAttr>();    } @@ -7283,6 +7407,22 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,      assert((NewFD->isInvalidDecl() || !D.isRedeclaration() ||              Previous.getResultKind() != LookupResult::FoundOverloaded) &&             "previous declaration set still overloaded"); + +    // Diagnose no-prototype function declarations with calling conventions that +    // don't support variadic calls. Only do this in C and do it after merging +    // possibly prototyped redeclarations. +    const FunctionType *FT = NewFD->getType()->castAs<FunctionType>(); +    if (isa<FunctionNoProtoType>(FT) && !D.isFunctionDefinition()) { +      CallingConv CC = FT->getExtInfo().getCC(); +      if (!supportsVariadicCall(CC)) { +        // Windows system headers sometimes accidentally use stdcall without +        // (void) parameters, so we relax this to a warning. +        int DiagID = +            CC == CC_X86StdCall ? diag::warn_cconv_knr : diag::err_cconv_knr; +        Diag(NewFD->getLocation(), DiagID) +            << FunctionType::getNameForCallConv(CC); +      } +    }    } else {      // C++11 [replacement.functions]p3:      //  The program's definitions shall not be specified as inline. @@ -7749,12 +7889,12 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,    // This rule is not present in C++1y, so we produce a backwards    // compatibility warning whenever it happens in C++11.    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); -  if (!getLangOpts().CPlusPlus1y && MD && MD->isConstexpr() && +  if (!getLangOpts().CPlusPlus14 && MD && MD->isConstexpr() &&        !MD->isStatic() && !isa<CXXConstructorDecl>(MD) &&        (MD->getTypeQualifiers() & Qualifiers::Const) == 0) {      CXXMethodDecl *OldMD = nullptr;      if (OldDecl) -      OldMD = dyn_cast<CXXMethodDecl>(OldDecl->getAsFunction()); +      OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl->getAsFunction());      if (!OldMD || !OldMD->isStatic()) {        const FunctionProtoType *FPT =          MD->getType()->castAs<FunctionProtoType>(); @@ -7771,7 +7911,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,                  .IgnoreParens().getAs<FunctionTypeLoc>())            AddConstLoc = getLocForEndOfToken(FTL.getRParenLoc()); -        Diag(MD->getLocation(), diag::warn_cxx1y_compat_constexpr_not_const) +        Diag(MD->getLocation(), diag::warn_cxx14_compat_constexpr_not_const)            << FixItHint::CreateInsertion(AddConstLoc, " const");        }      } @@ -7838,6 +7978,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,    }    // Semantic checking for this function declaration (in isolation). +    if (getLangOpts().CPlusPlus) {      // C++-specific checks.      if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD)) { @@ -7918,7 +8059,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,      // the function returns a UDT (class, struct, or union type) that is not C      // compatible, and if it does, warn the user.      // But, issue any diagnostic on the first declaration only. -    if (NewFD->isExternC() && Previous.empty()) { +    if (Previous.empty() && NewFD->isExternC()) {        QualType R = NewFD->getReturnType();        if (R->isIncompleteType() && !R->isVoidType())          Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete) @@ -8120,6 +8261,8 @@ namespace {      bool isPODType;      bool isReferenceType; +    bool isInitList; +    llvm::SmallVector<unsigned, 4> InitFieldIndex;    public:      typedef EvaluatedExprVisitor<SelfReferenceChecker> Inherited; @@ -8128,6 +8271,7 @@ namespace {        isPODType = false;        isRecordType = false;        isReferenceType = false; +      isInitList = false;        if (ValueDecl *VD = dyn_cast<ValueDecl>(OrigDecl)) {          isPODType = VD->getType().isPODType(S.Context);          isRecordType = VD->getType()->isRecordType(); @@ -8135,25 +8279,122 @@ namespace {        }      } +    // For most expressions, just call the visitor.  For initializer lists, +    // track the index of the field being initialized since fields are +    // initialized in order allowing use of previously initialized fields. +    void CheckExpr(Expr *E) { +      InitListExpr *InitList = dyn_cast<InitListExpr>(E); +      if (!InitList) { +        Visit(E); +        return; +      } + +      // Track and increment the index here. +      isInitList = true; +      InitFieldIndex.push_back(0); +      for (auto Child : InitList->children()) { +        CheckExpr(cast<Expr>(Child)); +        ++InitFieldIndex.back(); +      } +      InitFieldIndex.pop_back(); +    } + +    // Returns true if MemberExpr is checked and no futher checking is needed. +    // Returns false if additional checking is required. +    bool CheckInitListMemberExpr(MemberExpr *E, bool CheckReference) { +      llvm::SmallVector<FieldDecl*, 4> Fields; +      Expr *Base = E; +      bool ReferenceField = false; + +      // Get the field memebers used. +      while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) { +        FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); +        if (!FD) +          return false; +        Fields.push_back(FD); +        if (FD->getType()->isReferenceType()) +          ReferenceField = true; +        Base = ME->getBase()->IgnoreParenImpCasts(); +      } + +      // Keep checking only if the base Decl is the same. +      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base); +      if (!DRE || DRE->getDecl() != OrigDecl) +        return false; + +      // A reference field can be bound to an unininitialized field. +      if (CheckReference && !ReferenceField) +        return true; + +      // Convert FieldDecls to their index number. +      llvm::SmallVector<unsigned, 4> UsedFieldIndex; +      for (auto I = Fields.rbegin(), E = Fields.rend(); I != E; ++I) { +        UsedFieldIndex.push_back((*I)->getFieldIndex()); +      } + +      // See if a warning is needed by checking the first difference in index +      // numbers.  If field being used has index less than the field being +      // initialized, then the use is safe. +      for (auto UsedIter = UsedFieldIndex.begin(), +                UsedEnd = UsedFieldIndex.end(), +                OrigIter = InitFieldIndex.begin(), +                OrigEnd = InitFieldIndex.end(); +           UsedIter != UsedEnd && OrigIter != OrigEnd; ++UsedIter, ++OrigIter) { +        if (*UsedIter < *OrigIter) +          return true; +        if (*UsedIter > *OrigIter) +          break; +      } + +      // TODO: Add a different warning which will print the field names. +      HandleDeclRefExpr(DRE); +      return true; +    } +      // For most expressions, the cast is directly above the DeclRefExpr.      // For conditional operators, the cast can be outside the conditional      // operator if both expressions are DeclRefExpr's.      void HandleValue(Expr *E) { -      if (isReferenceType) -        return; -      E = E->IgnoreParenImpCasts(); +      E = E->IgnoreParens();        if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(E)) {          HandleDeclRefExpr(DRE);          return;        }        if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { +        Visit(CO->getCond());          HandleValue(CO->getTrueExpr());          HandleValue(CO->getFalseExpr());          return;        } +      if (BinaryConditionalOperator *BCO = +              dyn_cast<BinaryConditionalOperator>(E)) { +        Visit(BCO->getCond()); +        HandleValue(BCO->getFalseExpr()); +        return; +      } + +      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { +        HandleValue(OVE->getSourceExpr()); +        return; +      } + +      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { +        if (BO->getOpcode() == BO_Comma) { +          Visit(BO->getLHS()); +          HandleValue(BO->getRHS()); +          return; +        } +      } +        if (isa<MemberExpr>(E)) { +        if (isInitList) { +          if (CheckInitListMemberExpr(cast<MemberExpr>(E), +                                      false /*CheckReference*/)) +            return; +        } +          Expr *Base = E->IgnoreParenImpCasts();          while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) {            // Check for static member variables and don't warn on them. @@ -8165,24 +8406,32 @@ namespace {            HandleDeclRefExpr(DRE);          return;        } + +      Visit(E);      } -    // Reference types are handled here since all uses of references are -    // bad, not just r-value uses. +    // Reference types not handled in HandleValue are handled here since all +    // uses of references are bad, not just r-value uses.      void VisitDeclRefExpr(DeclRefExpr *E) {        if (isReferenceType)          HandleDeclRefExpr(E);      }      void VisitImplicitCastExpr(ImplicitCastExpr *E) { -      if (E->getCastKind() == CK_LValueToRValue || -          (isRecordType && E->getCastKind() == CK_NoOp)) +      if (E->getCastKind() == CK_LValueToRValue) {          HandleValue(E->getSubExpr()); +        return; +      }        Inherited::VisitImplicitCastExpr(E);      }      void VisitMemberExpr(MemberExpr *E) { +      if (isInitList) { +        if (CheckInitListMemberExpr(E, true /*CheckReference*/)) +          return; +      } +        // Don't warn on arrays since they can be treated as pointers.        if (E->getType()->canDecayToPointerType()) return; @@ -8209,11 +8458,14 @@ namespace {      }      void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { -      if (E->getNumArgs() > 0) -        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getArg(0))) -          HandleDeclRefExpr(DRE); +      Expr *Callee = E->getCallee(); -      Inherited::VisitCXXOperatorCallExpr(E); +      if (isa<UnresolvedLookupExpr>(Callee)) +        return Inherited::VisitCXXOperatorCallExpr(E); + +      Visit(Callee); +      for (auto Arg: E->arguments()) +        HandleValue(Arg->IgnoreParenImpCasts());      }      void VisitUnaryOperator(UnaryOperator *E) { @@ -8224,11 +8476,65 @@ namespace {            HandleValue(E->getSubExpr());          return;        } + +      if (E->isIncrementDecrementOp()) { +        HandleValue(E->getSubExpr()); +        return; +      } +        Inherited::VisitUnaryOperator(E);      }      void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; } +    void VisitCXXConstructExpr(CXXConstructExpr *E) { +      if (E->getConstructor()->isCopyConstructor()) { +        Expr *ArgExpr = E->getArg(0); +        if (InitListExpr *ILE = dyn_cast<InitListExpr>(ArgExpr)) +          if (ILE->getNumInits() == 1) +            ArgExpr = ILE->getInit(0); +        if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) +          if (ICE->getCastKind() == CK_NoOp) +            ArgExpr = ICE->getSubExpr(); +        HandleValue(ArgExpr); +        return; +      } +      Inherited::VisitCXXConstructExpr(E); +    } + +    void VisitCallExpr(CallExpr *E) { +      // Treat std::move as a use. +      if (E->getNumArgs() == 1) { +        if (FunctionDecl *FD = E->getDirectCallee()) { +          if (FD->isInStdNamespace() && FD->getIdentifier() && +              FD->getIdentifier()->isStr("move")) { +            HandleValue(E->getArg(0)); +            return; +          } +        } +      } + +      Inherited::VisitCallExpr(E); +    } + +    void VisitBinaryOperator(BinaryOperator *E) { +      if (E->isCompoundAssignmentOp()) { +        HandleValue(E->getLHS()); +        Visit(E->getRHS()); +        return; +      } + +      Inherited::VisitBinaryOperator(E); +    } + +    // A custom visitor for BinaryConditionalOperator is needed because the +    // regular visitor would check the condition and true expression separately +    // but both point to the same place giving duplicate diagnostics. +    void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) { +      Visit(E->getCond()); +      Visit(E->getFalseExpr()); +    } +      void HandleDeclRefExpr(DeclRefExpr *DRE) {        Decl* ReferenceDecl = DRE->getDecl();        if (OrigDecl != ReferenceDecl) return; @@ -8268,7 +8574,7 @@ namespace {              if (DRE->getDecl() == OrigDecl)                return; -    SelfReferenceChecker(S, OrigDecl).Visit(E); +    SelfReferenceChecker(S, OrigDecl).CheckExpr(E);    }  } @@ -8279,8 +8585,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,                                  bool DirectInit, bool TypeMayContainAuto) {    // If there is no declaration, there was an error parsing it.  Just ignore    // the initializer. -  if (!RealDecl || RealDecl->isInvalidDecl()) +  if (!RealDecl || RealDecl->isInvalidDecl()) { +    CorrectDelayedTyposInExpr(Init);      return; +  }    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {      // With declarators parsed the way they are, the parser cannot @@ -8511,6 +8819,21 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,        Args = MultiExprArg(CXXDirectInit->getExprs(),                            CXXDirectInit->getNumExprs()); +    // Try to correct any TypoExprs in the initialization arguments. +    for (size_t Idx = 0; Idx < Args.size(); ++Idx) { +      ExprResult Res = +          CorrectDelayedTyposInExpr(Args[Idx], [this, Entity, Kind](Expr *E) { +            InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E)); +            return Init.Failed() ? ExprError() : E; +          }); +      if (Res.isInvalid()) { +        VDecl->setInvalidDecl(); +        return; +      } +      if (Res.get() != Args[Idx]) +        Args[Idx] = Res.get(); +    } +      InitializationSequence InitSeq(*this, Entity, Kind, Args);      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);      if (Result.isInvalid()) { @@ -9124,15 +9447,15 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {    if (var->isThisDeclarationADefinition() &&        ActiveTemplateInstantiations.empty()) {      PragmaStack<StringLiteral *> *Stack = nullptr; -    int SectionFlags = PSF_Implicit | PSF_Read; +    int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read;      if (var->getType().isConstQualified())        Stack = &ConstSegStack;      else if (!var->getInit()) {        Stack = &BSSSegStack; -      SectionFlags |= PSF_Write; +      SectionFlags |= ASTContext::PSF_Write;      } else {        Stack = &DataSegStack; -      SectionFlags |= PSF_Write; +      SectionFlags |= ASTContext::PSF_Write;      }      if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue)        var->addAttr( @@ -9244,7 +9567,7 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {    // Static locals inherit dll attributes from their function.    if (VD->isStaticLocal()) {      if (FunctionDecl *FD = -            dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) { +            dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod())) {        if (Attr *A = getDLLAttr(FD)) {          auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext()));          NewAttr->setInherited(true); @@ -9253,8 +9576,11 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {      }    } +  // Grab the dllimport or dllexport attribute off of the VarDecl. +  const InheritableAttr *DLLAttr = getDLLAttr(VD); +    // Imported static data members cannot be defined out-of-line. -  if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) { +  if (const auto *IA = dyn_cast_or_null<DLLImportAttr>(DLLAttr)) {      if (VD->isStaticDataMember() && VD->isOutOfLine() &&          VD->isThisDeclarationADefinition()) {        // We allow definitions of dllimport class template static data members @@ -9275,6 +9601,14 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {      }    } +  // dllimport/dllexport variables cannot be thread local, their TLS index +  // isn't exported with the variable. +  if (DLLAttr && VD->getTLSKind()) { +    Diag(VD->getLocation(), diag::err_attribute_dll_thread_local) << VD +                                                                  << DLLAttr; +    VD->setInvalidDecl(); +  } +    if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {      if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {        Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr; @@ -9466,12 +9800,12 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {    // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.    // C++03 [dcl.stc]p2 also permits 'auto'. -  VarDecl::StorageClass StorageClass = SC_None; +  StorageClass SC = SC_None;    if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { -    StorageClass = SC_Register; +    SC = SC_Register;    } else if (getLangOpts().CPlusPlus &&               DS.getStorageClassSpec() == DeclSpec::SCS_auto) { -    StorageClass = SC_Auto; +    SC = SC_Auto;    } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {      Diag(DS.getStorageClassSpecLoc(),           diag::err_invalid_storage_class_in_func_decl); @@ -9545,7 +9879,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {                                      D.getLocStart(),                                      D.getIdentifierLoc(), II,                                      parmDeclType, TInfo, -                                    StorageClass); +                                    SC);    if (D.isInvalidType())      New->setInvalidDecl(); @@ -9637,7 +9971,7 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param,  ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,                                    SourceLocation NameLoc, IdentifierInfo *Name,                                    QualType T, TypeSourceInfo *TSInfo, -                                  VarDecl::StorageClass StorageClass) { +                                  StorageClass SC) {    // In ARC, infer a lifetime qualifier for appropriate parameter types.    if (getLangOpts().ObjCAutoRefCount &&        T.getObjCLifetime() == Qualifiers::OCL_None && @@ -9663,8 +9997,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,    ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,                                           Context.getAdjustedParameterType(T),  -                                         TSInfo, -                                         StorageClass, nullptr); +                                         TSInfo, SC, nullptr);    // Parameters can not be abstract class types.    // For record types, this is done by the AbstractClassUsageDiagnoser once @@ -9850,6 +10183,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,    // Add the captures to the LSI so they can be noted as already    // captured within tryCaptureVar.  +  auto I = LambdaClass->field_begin();    for (const auto &C : LambdaClass->captures()) {      if (C.capturesVariable()) {        VarDecl *VD = C.getCapturedVar(); @@ -9858,7 +10192,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,        QualType CaptureType = VD->getType();        const bool ByRef = C.getCaptureKind() == LCK_ByRef;        LSI->addCapture(VD, /*IsBlock*/false, ByRef,  -          /*RefersToEnclosingLocal*/true, C.getLocation(), +          /*RefersToEnclosingVariableOrCapture*/true, C.getLocation(),            /*EllipsisLoc*/C.isPackExpansion()                            ? C.getEllipsisLoc() : SourceLocation(),            CaptureType, /*Expr*/ nullptr); @@ -9866,7 +10200,10 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,      } else if (C.capturesThis()) {        LSI->addThisCapture(/*Nested*/ false, C.getLocation(),                                 S.getCurrentThisType(), /*Expr*/ nullptr); +    } else { +      LSI->addVLATypeCapture(C.getLocation(), I->getType());      } +    ++I;    }  } @@ -10107,7 +10444,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,    if (FD) {      FD->setBody(Body); -    if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && Body && +    if (getLangOpts().CPlusPlus14 && !FD->isInvalidDecl() && Body &&          !FD->isDependentContext() && FD->getReturnType()->isUndeducedType()) {        // If the function has a deduced result type but contains no 'return'        // statements, the result type as written must be exactly 'auto', and @@ -10118,8 +10455,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,          FD->setInvalidDecl();        } else {          // Substitute 'void' for the 'auto' in the type. -        TypeLoc ResultType = FD->getTypeSourceInfo()->getTypeLoc(). -            IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc(); +        TypeLoc ResultType = getReturnTypeLoc(FD);          Context.adjustDeducedFunctionResultType(              FD, SubstAutoType(ResultType.getType(), Context.VoidTy));        } @@ -10154,9 +10490,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,        DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(),                                               FD->getReturnType(), FD); -      // If this is a constructor, we need a vtable. +      // If this is a structor, we need a vtable.        if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))          MarkVTableUsed(FD->getLocation(), Constructor->getParent()); +      else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(FD)) +        MarkVTableUsed(FD->getLocation(), Destructor->getParent());        // Try to apply the named return value optimization. We have to check        // if we can do this here because lambdas keep return statements around @@ -10265,7 +10603,19 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,           !CheckConstexprFunctionBody(FD, Body)))        FD->setInvalidDecl(); -    assert(ExprCleanupObjects.empty() && "Leftover temporaries in function"); +    if (FD && FD->hasAttr<NakedAttr>()) { +      for (const Stmt *S : Body->children()) { +        if (!isa<AsmStmt>(S) && !isa<NullStmt>(S)) { +          Diag(S->getLocStart(), diag::err_non_asm_stmt_in_naked_function); +          Diag(FD->getAttr<NakedAttr>()->getLocation(), diag::note_attribute); +          FD->setInvalidDecl(); +          break; +        } +      } +    } + +    assert(ExprCleanupObjects.size() == ExprEvalContexts.back().NumCleanupObjects +           && "Leftover temporaries in function");      assert(!ExprNeedsCleanups && "Unaccounted cleanups in function");      assert(MaybeODRUseExprs.empty() &&             "Leftover expressions for odr-use checking"); @@ -10329,10 +10679,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,    // function declaration is going to be treated as an error.    if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) {      TypoCorrection Corrected; -    DeclFilterCCC<FunctionDecl> Validator; -    if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), -                                      LookupOrdinaryName, S, nullptr, Validator, -                                      CTK_NonError))) +    if (S && +        (Corrected = CorrectTypo( +             DeclarationNameInfo(&II, Loc), LookupOrdinaryName, S, nullptr, +             llvm::make_unique<DeclFilterCCC<FunctionDecl>>(), CTK_NonError)))        diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion),                     /*ErrorRecovery*/false);    } @@ -10360,6 +10710,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,                                               /*RefQualifierLoc=*/NoLoc,                                               /*ConstQualifierLoc=*/NoLoc,                                               /*VolatileQualifierLoc=*/NoLoc, +                                             /*RestrictQualifierLoc=*/NoLoc,                                               /*MutableLoc=*/NoLoc,                                               EST_None,                                               /*ESpecLoc=*/NoLoc, @@ -10367,6 +10718,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,                                               /*ExceptionRanges=*/nullptr,                                               /*NumExceptions=*/0,                                               /*NoexceptExpr=*/nullptr, +                                             /*ExceptionSpecTokens=*/nullptr,                                               Loc, Loc, D),                  DS.getAttributes(),                  SourceLocation()); @@ -11262,9 +11614,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,              } else {                // If the type is currently being defined, complain                // about a nested redefinition. -              const TagType *Tag -                = cast<TagType>(Context.getTagDeclType(PrevTagDecl)); -              if (Tag->isBeingDefined()) { +              auto *TD = Context.getTagDeclType(PrevTagDecl)->getAsTagDecl(); +              if (TD->isBeingDefined()) {                  Diag(NameLoc, diag::err_nested_redefinition) << Name;                  Diag(PrevTagDecl->getLocation(),                       diag::note_previous_definition); @@ -11454,7 +11805,7 @@ CreateNewDecl:        // CheckMemberSpecialization, below.        if (!isExplicitSpecialization &&            (TUK == TUK_Definition || TUK == TUK_Declaration) && -          diagnoseQualifiedDeclaration(SS, DC, OrigName, NameLoc)) +          diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc))          Invalid = true;        New->setQualifierInfo(SS.getWithLocInContext(Context)); @@ -12430,8 +12781,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,          continue;        }        // Okay, we have a legal flexible array member at the end of the struct. -      if (Record) -        Record->setHasFlexibleArrayMember(true); +      Record->setHasFlexibleArrayMember(true);      } else if (!FDTy->isDependentType() &&                 RequireCompleteType(FD->getLocation(), FD->getType(),                                     diag::err_field_incomplete)) { @@ -12440,11 +12790,11 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,        EnclosingDecl->setInvalidDecl();        continue;      } else if (const RecordType *FDTTy = FDTy->getAs<RecordType>()) { -      if (FDTTy->getDecl()->hasFlexibleArrayMember()) { -        // If this is a member of a union, then entire union becomes "flexible". -        if (Record && Record->isUnion()) { -          Record->setHasFlexibleArrayMember(true); -        } else { +      if (Record && FDTTy->getDecl()->hasFlexibleArrayMember()) { +        // A type which contains a flexible array member is considered to be a +        // flexible array member. +        Record->setHasFlexibleArrayMember(true); +        if (!Record->isUnion()) {            // If this is a struct/class and this is not the last element, reject            // it.  Note that GCC supports variable sized arrays in the middle of            // structures. @@ -12456,8 +12806,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,              // other structs as an extension.              Diag(FD->getLocation(), diag::ext_flexible_array_in_struct)                << FD->getDeclName(); -            if (Record) -              Record->setHasFlexibleArrayMember(true);            }          }        } @@ -13171,6 +13519,49 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,    }  } +bool +Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, +                        bool AllowMask) const { +  FlagEnumAttr *FEAttr = ED->getAttr<FlagEnumAttr>(); +  assert(FEAttr && "looking for value in non-flag enum"); + +  llvm::APInt FlagMask = ~FEAttr->getFlagBits(); +  unsigned Width = FlagMask.getBitWidth(); + +  // We will try a zero-extended value for the regular check first. +  llvm::APInt ExtVal = Val.zextOrSelf(Width); + +  // A value is in a flag enum if either its bits are a subset of the enum's +  // flag bits (the first condition) or we are allowing masks and the same is +  // true of its complement (the second condition). When masks are allowed, we +  // allow the common idiom of ~(enum1 | enum2) to be a valid enum value. +  // +  // While it's true that any value could be used as a mask, the assumption is +  // that a mask will have all of the insignificant bits set. Anything else is +  // likely a logic error. +  if (!(FlagMask & ExtVal)) +    return true; + +  if (AllowMask) { +    // Try a one-extended value instead. This can happen if the enum is wider +    // than the constant used, in C with extensions to allow for wider enums. +    // The mask will still have the correct behaviour, so we give the user the +    // benefit of the doubt. +    // +    // FIXME: This heuristic can cause weird results if the enum was extended +    // to a larger type and is signed, because then bit-masks of smaller types +    // that get extended will fall out of range (e.g. ~0x1u). We currently don't +    // detect that case and will get a false positive for it. In most cases, +    // though, it can be fixed by making it a signed type (e.g. ~0x1), so it may +    // be fine just to accept this as a warning. +    ExtVal |= llvm::APInt::getHighBitsSet(Width, Width - Val.getBitWidth()); +    if (!(FlagMask & ~ExtVal)) +      return true; +  } + +  return false; +} +  void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,                           SourceLocation RBraceLoc, Decl *EnumDeclX,                           ArrayRef<Decl *> Elements, @@ -13256,10 +13647,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,        BestPromotionType = Context.getPromotedIntegerType(BestType);      else        BestPromotionType = BestType; -    // We don't need to set BestWidth, because BestType is going to be the type -    // of the enumerators, but we do anyway because otherwise some compilers -    // warn that it might be used uninitialized. -    BestWidth = CharWidth; + +    BestWidth = Context.getIntWidth(BestType);    }    else if (NumNegativeBits) {      // If there is a negative value, figure out the smallest integer type (of @@ -13324,10 +13713,15 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,      }    } +  FlagEnumAttr *FEAttr = Enum->getAttr<FlagEnumAttr>(); +  if (FEAttr) +    FEAttr->getFlagBits() = llvm::APInt(BestWidth, 0); +    // Loop over all of the enumerator constants, changing their types to match -  // the type of the enum if needed. -  for (unsigned i = 0, e = Elements.size(); i != e; ++i) { -    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]); +  // the type of the enum if needed. If we have a flag type, we also prepare the +  // FlagBits cache. +  for (auto *D : Elements) { +    auto *ECD = cast_or_null<EnumConstantDecl>(D);      if (!ECD) continue;  // Already issued a diagnostic.      // Standard C says the enumerators have int type, but we allow, as an @@ -13357,7 +13751,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,          // enum-specifier, each enumerator has the type of its          // enumeration.          ECD->setType(EnumType); -      continue; +      goto flagbits;      } else {        NewTy = BestType;        NewWidth = BestWidth; @@ -13384,8 +13778,32 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,        ECD->setType(EnumType);      else        ECD->setType(NewTy); + +flagbits: +    // Check to see if we have a constant with exactly one bit set. Note that x +    // & (x - 1) will be nonzero if and only if x has more than one bit set. +    if (FEAttr) { +      llvm::APInt ExtVal = InitVal.zextOrSelf(BestWidth); +      if (ExtVal != 0 && !(ExtVal & (ExtVal - 1))) { +        FEAttr->getFlagBits() |= ExtVal; +      } +    }    } +  if (FEAttr) { +    for (Decl *D : Elements) { +      EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D); +      if (!ECD) continue;  // Already issued a diagnostic. + +      llvm::APSInt InitVal = ECD->getInitVal(); +      if (InitVal != 0 && !IsValueInFlagEnum(Enum, InitVal, true)) +        Diag(ECD->getLocation(), diag::warn_flag_enum_constant_out_of_range) +          << ECD << Enum; +    } +  } + + +    Enum->completeDefinition(BestType, BestPromotionType,                             NumPositiveBits, NumNegativeBits); @@ -13455,6 +13873,9 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc,    if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule)      Diag(ImportLoc, diag::err_module_self_import)          << Mod->getFullModuleName() << getLangOpts().CurrentModule; +  else if (Mod->getTopLevelModuleName() == getLangOpts().ImplementationOfModule) +    Diag(ImportLoc, diag::err_module_import_in_implementation) +        << Mod->getFullModuleName() << getLangOpts().ImplementationOfModule;    SmallVector<SourceLocation, 2> IdentifierLocs;    Module *ModCheck = Mod; @@ -13575,5 +13996,6 @@ AvailabilityResult Sema::getCurContextAvailability() const {              dyn_cast<ObjCImplementationDecl>(D)) {      D = ID->getClassInterface();    } -  return D->getAvailability(); +  // Recover from user error. +  return D ? D->getAvailability() : AR_Available;  } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 61683cd87579..17a849ea7af0 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -29,6 +29,7 @@  #include "clang/Sema/Lookup.h"  #include "clang/Sema/Scope.h"  #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/MathExtras.h"  using namespace clang;  using namespace sema; @@ -88,21 +89,39 @@ static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {    return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();  } +static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) { +  if (const auto *FD = dyn_cast<FunctionDecl>(D)) +    return FD->getParamDecl(Idx)->getSourceRange(); +  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) +    return MD->parameters()[Idx]->getSourceRange(); +  if (const auto *BD = dyn_cast<BlockDecl>(D)) +    return BD->getParamDecl(Idx)->getSourceRange(); +  return SourceRange(); +} +  static QualType getFunctionOrMethodResultType(const Decl *D) {    if (const FunctionType *FnTy = D->getFunctionType())      return cast<FunctionType>(FnTy)->getReturnType();    return cast<ObjCMethodDecl>(D)->getReturnType();  } +static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) { +  if (const auto *FD = dyn_cast<FunctionDecl>(D)) +    return FD->getReturnTypeSourceRange(); +  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) +    return MD->getReturnTypeSourceRange(); +  return SourceRange(); +} +  static bool isFunctionOrMethodVariadic(const Decl *D) {    if (const FunctionType *FnTy = D->getFunctionType()) {      const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);      return proto->isVariadic(); -  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) -    return BD->isVariadic(); -  else { -    return cast<ObjCMethodDecl>(D)->isVariadic();    } +  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) +    return BD->isVariadic(); + +  return cast<ObjCMethodDecl>(D)->isVariadic();  }  static bool isInstanceMethod(const Decl *D) { @@ -148,30 +167,43 @@ static unsigned getNumAttributeArgs(const AttributeList &Attr) {    return Attr.getNumArgs() + Attr.hasParsedType();  } -/// \brief Check if the attribute has exactly as many args as Num. May -/// output an error. -static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, -                                  unsigned Num) { -  if (getNumAttributeArgs(Attr) != Num) { -    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) -      << Attr.getName() << Num; +template <typename Compare> +static bool checkAttributeNumArgsImpl(Sema &S, const AttributeList &Attr, +                                      unsigned Num, unsigned Diag, +                                      Compare Comp) { +  if (Comp(getNumAttributeArgs(Attr), Num)) { +    S.Diag(Attr.getLoc(), Diag) << Attr.getName() << Num;      return false;    }    return true;  } +/// \brief Check if the attribute has exactly as many args as Num. May +/// output an error. +static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, +                                  unsigned Num) { +  return checkAttributeNumArgsImpl(S, Attr, Num, +                                   diag::err_attribute_wrong_number_arguments, +                                   std::not_equal_to<unsigned>()); +} +  /// \brief Check if the attribute has at least as many args as Num. May  /// output an error.  static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,                                           unsigned Num) { -  if (getNumAttributeArgs(Attr) < Num) { -    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) -      << Attr.getName() << Num; -    return false; -  } +  return checkAttributeNumArgsImpl(S, Attr, Num, +                                   diag::err_attribute_too_few_arguments, +                                   std::less<unsigned>()); +} -  return true; +/// \brief Check if the attribute has at most as many args as Num. May +/// output an error. +static bool checkAttributeAtMostNumArgs(Sema &S, const AttributeList &Attr, +                                         unsigned Num) { +  return checkAttributeNumArgsImpl(S, Attr, Num, +                                   diag::err_attribute_too_many_arguments, +                                   std::greater<unsigned>());  }  /// \brief If Expr is a valid integer constant, get the value of the integer @@ -192,6 +224,13 @@ static bool checkUInt32Argument(Sema &S, const AttributeList &Attr,          << Expr->getSourceRange();      return false;    } + +  if (!I.isIntN(32)) { +    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large) +        << I.toString(10, false) << 32 << /* Unsigned */ 1; +    return false; +  } +    Val = (uint32_t)I.getZExtValue();    return true;  } @@ -528,10 +567,6 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,  // Attribute Implementations  //===----------------------------------------------------------------------===// -// FIXME: All this manual attribute parsing code is gross. At the -// least add some helper functions to check most argument patterns (# -// and types of args). -  static void handlePtGuardedVarAttr(Sema &S, Decl *D,                                     const AttributeList &Attr) {    if (!threadSafetyCheckIsPointer(S, D, Attr)) @@ -706,11 +741,9 @@ static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,    if (!checkTryLockFunAttrCommon(S, D, Attr, Args))      return; -  D->addAttr(::new (S.Context) -             ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context, -                                          Attr.getArgAsExpr(0), -                                          Args.data(), Args.size(), -                                          Attr.getAttributeSpellingListIndex())); +  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr( +      Attr.getRange(), S.Context, Attr.getArgAsExpr(0), Args.data(), +      Args.size(), Attr.getAttributeSpellingListIndex()));  }  static void handleLockReturnedAttr(Sema &S, Decl *D, @@ -828,8 +861,14 @@ static void handleCallableWhenAttr(Sema &S, Decl *D,      StringRef StateString;      SourceLocation Loc; -    if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc)) -      return; +    if (Attr.isArgIdent(ArgIndex)) { +      IdentifierLoc *Ident = Attr.getArgAsIdent(ArgIndex); +      StateString = Ident->Ident->getName(); +      Loc = Ident->Loc; +    } else { +      if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc)) +        return; +    }      if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,                                                       CallableState)) { @@ -849,8 +888,6 @@ static void handleCallableWhenAttr(Sema &S, Decl *D,  static void handleParamTypestateAttr(Sema &S, Decl *D,                                      const AttributeList &Attr) { -  if (!checkAttributeNumArgs(S, Attr, 1)) return; -        ParamTypestateAttr::ConsumedState ParamState;    if (Attr.isArgIdent(0)) { @@ -889,8 +926,6 @@ static void handleParamTypestateAttr(Sema &S, Decl *D,  static void handleReturnTypestateAttr(Sema &S, Decl *D,                                        const AttributeList &Attr) { -  if (!checkAttributeNumArgs(S, Attr, 1)) return; -      ReturnTypestateAttr::ConsumedState ReturnState;    if (Attr.isArgIdent(0)) { @@ -939,9 +974,6 @@ static void handleReturnTypestateAttr(Sema &S, Decl *D,  static void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) { -  if (!checkAttributeNumArgs(S, Attr, 1)) -    return; -      if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))      return; @@ -967,9 +999,6 @@ static void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr)  static void handleTestTypestateAttr(Sema &S, Decl *D,                                      const AttributeList &Attr) { -  if (!checkAttributeNumArgs(S, Attr, 1)) -    return; -      if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))      return; @@ -1101,30 +1130,39 @@ static void handleIBOutletCollection(Sema &S, Decl *D,                                      Attr.getAttributeSpellingListIndex()));  } -static void possibleTransparentUnionPointerType(QualType &T) { -  if (const RecordType *UT = T->getAsUnionType()) +bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { +  if (RefOkay) { +    if (T->isReferenceType()) +      return true; +  } else { +    T = T.getNonReferenceType(); +  } + +  // The nonnull attribute, and other similar attributes, can be applied to a +  // transparent union that contains a pointer type. +  if (const RecordType *UT = T->getAsUnionType()) {      if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {        RecordDecl *UD = UT->getDecl();        for (const auto *I : UD->fields()) {          QualType QT = I->getType(); -        if (QT->isAnyPointerType() || QT->isBlockPointerType()) { -          T = QT; -          return; -        } +        if (QT->isAnyPointerType() || QT->isBlockPointerType()) +          return true;        }      } +  } + +  return T->isAnyPointerType() || T->isBlockPointerType();  }  static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr, -                                SourceRange R, bool isReturnValue = false) { -  T = T.getNonReferenceType(); -  possibleTransparentUnionPointerType(T); - -  if (!T->isAnyPointerType() && !T->isBlockPointerType()) { -    S.Diag(Attr.getLoc(), -           isReturnValue ? diag::warn_attribute_return_pointers_only -                         : diag::warn_attribute_pointers_only) -      << Attr.getName() << R; +                                SourceRange AttrParmRange, +                                SourceRange TypeRange, +                                bool isReturnValue = false) { +  if (!S.isValidPointerAttrType(T)) { +    S.Diag(Attr.getLoc(), isReturnValue +                              ? diag::warn_attribute_return_pointers_only +                              : diag::warn_attribute_pointers_only) +        << Attr.getName() << AttrParmRange << TypeRange;      return false;    }    return true; @@ -1132,46 +1170,45 @@ static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr,  static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {    SmallVector<unsigned, 8> NonNullArgs; -  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) { -    Expr *Ex = Attr.getArgAsExpr(i); +  for (unsigned I = 0; I < Attr.getNumArgs(); ++I) { +    Expr *Ex = Attr.getArgAsExpr(I);      uint64_t Idx; -    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, i + 1, Ex, Idx)) +    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, I + 1, Ex, Idx))        return;      // Is the function argument a pointer type? -    // FIXME: Should also highlight argument in decl in the diagnostic. -    if (!attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr, -                             Ex->getSourceRange())) +    if (Idx < getFunctionOrMethodNumParams(D) && +        !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr, +                             Ex->getSourceRange(), +                             getFunctionOrMethodParamRange(D, Idx)))        continue;      NonNullArgs.push_back(Idx);    }    // If no arguments were specified to __attribute__((nonnull)) then all pointer -  // arguments have a nonnull attribute. -  if (NonNullArgs.empty()) { -    for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e; ++i) { -      QualType T = getFunctionOrMethodParamType(D, i).getNonReferenceType(); -      possibleTransparentUnionPointerType(T); -      if (T->isAnyPointerType() || T->isBlockPointerType()) -        NonNullArgs.push_back(i); +  // arguments have a nonnull attribute; warn if there aren't any. Skip this +  // check if the attribute came from a macro expansion or a template +  // instantiation. +  if (NonNullArgs.empty() && Attr.getLoc().isFileID() && +      S.ActiveTemplateInstantiations.empty()) { +    bool AnyPointers = isFunctionOrMethodVariadic(D); +    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); +         I != E && !AnyPointers; ++I) { +      QualType T = getFunctionOrMethodParamType(D, I); +      if (T->isDependentType() || S.isValidPointerAttrType(T)) +        AnyPointers = true;      } -    // No pointer arguments? -    if (NonNullArgs.empty()) { -      // Warn the trivial case only if attribute is not coming from a -      // macro instantiation. -      if (Attr.getLoc().isFileID()) -        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); -      return; -    } +    if (!AnyPointers) +      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);    } -  unsigned *start = &NonNullArgs[0]; -  unsigned size = NonNullArgs.size(); -  llvm::array_pod_sort(start, start + size); +  unsigned *Start = NonNullArgs.data(); +  unsigned Size = NonNullArgs.size(); +  llvm::array_pod_sort(Start, Start + Size);    D->addAttr(::new (S.Context) -             NonNullAttr(Attr.getRange(), S.Context, start, size, +             NonNullAttr(Attr.getRange(), S.Context, Start, Size,                           Attr.getAttributeSpellingListIndex()));  } @@ -1188,7 +1225,8 @@ static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,    }    // Is the argument a pointer type? -  if (!attrNonNullArgCheck(S, D->getType(), Attr, D->getSourceRange())) +  if (!attrNonNullArgCheck(S, D->getType(), Attr, SourceRange(), +                           D->getSourceRange()))      return;    D->addAttr(::new (S.Context) @@ -1199,7 +1237,8 @@ static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,  static void handleReturnsNonNullAttr(Sema &S, Decl *D,                                       const AttributeList &Attr) {    QualType ResultType = getFunctionOrMethodResultType(D); -  if (!attrNonNullArgCheck(S, ResultType, Attr, Attr.getRange(), +  SourceRange SR = getFunctionOrMethodResultSourceRange(D); +  if (!attrNonNullArgCheck(S, ResultType, Attr, SourceRange(), SR,                             /* isReturnValue */ true))      return; @@ -1208,6 +1247,65 @@ static void handleReturnsNonNullAttr(Sema &S, Decl *D,                                 Attr.getAttributeSpellingListIndex()));  } +static void handleAssumeAlignedAttr(Sema &S, Decl *D, +                                    const AttributeList &Attr) { +  Expr *E = Attr.getArgAsExpr(0), +       *OE = Attr.getNumArgs() > 1 ? Attr.getArgAsExpr(1) : nullptr; +  S.AddAssumeAlignedAttr(Attr.getRange(), D, E, OE, +                         Attr.getAttributeSpellingListIndex()); +} + +void Sema::AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, +                                Expr *OE, unsigned SpellingListIndex) { +  QualType ResultType = getFunctionOrMethodResultType(D); +  SourceRange SR = getFunctionOrMethodResultSourceRange(D); + +  AssumeAlignedAttr TmpAttr(AttrRange, Context, E, OE, SpellingListIndex); +  SourceLocation AttrLoc = AttrRange.getBegin(); + +  if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) { +    Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only) +      << &TmpAttr << AttrRange << SR; +    return; +  } + +  if (!E->isValueDependent()) { +    llvm::APSInt I(64); +    if (!E->isIntegerConstantExpr(I, Context)) { +      if (OE) +        Diag(AttrLoc, diag::err_attribute_argument_n_type) +          << &TmpAttr << 1 << AANT_ArgumentIntegerConstant +          << E->getSourceRange(); +      else +        Diag(AttrLoc, diag::err_attribute_argument_type) +          << &TmpAttr << AANT_ArgumentIntegerConstant +          << E->getSourceRange(); +      return; +    } + +    if (!I.isPowerOf2()) { +      Diag(AttrLoc, diag::err_alignment_not_power_of_two) +        << E->getSourceRange(); +      return; +    } +  } + +  if (OE) { +    if (!OE->isValueDependent()) { +      llvm::APSInt I(64); +      if (!OE->isIntegerConstantExpr(I, Context)) { +        Diag(AttrLoc, diag::err_attribute_argument_n_type) +          << &TmpAttr << 2 << AANT_ArgumentIntegerConstant +          << OE->getSourceRange(); +        return; +      } +    } +  } + +  D->addAttr(::new (Context) +            AssumeAlignedAttr(AttrRange, Context, E, OE, SpellingListIndex)); +} +  static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {    // This attribute must be applied to a function declaration. The first    // argument to the attribute must be an identifier, the name of the resource, @@ -1286,13 +1384,26 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {      // Check we don't have a conflict with another ownership attribute.      for (const auto *I : D->specific_attrs<OwnershipAttr>()) { -      // FIXME: A returns attribute should conflict with any returns attribute -      // with a different index too. +      // Cannot have two ownership attributes of different kinds for the same +      // index.        if (I->getOwnKind() != K && I->args_end() !=            std::find(I->args_begin(), I->args_end(), Idx)) {          S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)            << AL.getName() << I;          return; +      } else if (K == OwnershipAttr::Returns && +                 I->getOwnKind() == OwnershipAttr::Returns) { +        // A returns attribute conflicts with any other returns attribute using +        // a different index. Note, diagnostic reporting is 1-based, but stored +        // argument indexes are 0-based. +        if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) { +          S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch) +              << *(I->args_begin()) + 1; +          if (I->args_size()) +            S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch) +                << (unsigned)Idx + 1 << Ex->getSourceRange(); +          return; +        }        }      }      OwnershipArgs.push_back(Idx); @@ -1586,15 +1697,8 @@ static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {  }  static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { -  // check the attribute arguments. -  if (Attr.getNumArgs() > 1) { -    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) -      << Attr.getName() << 1; -    return; -  } -    uint32_t priority = ConstructorAttr::DefaultPriority; -  if (Attr.getNumArgs() > 0 && +  if (Attr.getNumArgs() &&        !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))      return; @@ -1604,15 +1708,8 @@ static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {  }  static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { -  // check the attribute arguments. -  if (Attr.getNumArgs() > 1) { -    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) -      << Attr.getName() << 1; -    return; -  } -    uint32_t priority = DestructorAttr::DefaultPriority; -  if (Attr.getNumArgs() > 0 && +  if (Attr.getNumArgs() &&        !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))      return; @@ -1624,16 +1721,9 @@ static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {  template <typename AttrTy>  static void handleAttrWithMessage(Sema &S, Decl *D,                                    const AttributeList &Attr) { -  unsigned NumArgs = Attr.getNumArgs(); -  if (NumArgs > 1) { -    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) -      << Attr.getName() << 1; -    return; -  } -    // Handle the case where the attribute has a text message.    StringRef Str; -  if (NumArgs == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) +  if (Attr.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str))      return;    D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str, @@ -2036,13 +2126,6 @@ static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {  }  static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { -  // check the attribute arguments. -  if (Attr.getNumArgs() > 2) { -    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) -      << Attr.getName() << 2; -    return; -  } -    unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;    if (Attr.getNumArgs() > 0) {      Expr *E = Attr.getArgAsExpr(0); @@ -2349,10 +2432,9 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {        !isCFStringType(Ty, S.Context) &&        (!Ty->isPointerType() ||         !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { -    // FIXME: Should highlight the actual expression that has the wrong type.      S.Diag(Attr.getLoc(), diag::err_format_attribute_not) -    << (not_nsstring_type ? "a string type" : "an NSString") -       << IdxExpr->getSourceRange(); +        << (not_nsstring_type ? "a string type" : "an NSString") +        << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);      return;    }    Ty = getFunctionOrMethodResultType(D); @@ -2360,10 +2442,9 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {        !isCFStringType(Ty, S.Context) &&        (!Ty->isPointerType() ||         !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { -    // FIXME: Should highlight the actual expression that has the wrong type.      S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) -    << (not_nsstring_type ? "string type" : "NSString") -       << IdxExpr->getSourceRange(); +        << (not_nsstring_type ? "string type" : "NSString") +        << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);      return;    } @@ -2534,23 +2615,24 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {    if (Kind == CFStringFormat) {      if (!isCFStringType(Ty, S.Context)) {        S.Diag(Attr.getLoc(), diag::err_format_attribute_not) -        << "a CFString" << IdxExpr->getSourceRange(); +        << "a CFString" << IdxExpr->getSourceRange() +        << getFunctionOrMethodParamRange(D, ArgIdx);        return;      }    } else if (Kind == NSStringFormat) {      // FIXME: do we need to check if the type is NSString*?  What are the      // semantics?      if (!isNSStringType(Ty, S.Context)) { -      // FIXME: Should highlight the actual expression that has the wrong type.        S.Diag(Attr.getLoc(), diag::err_format_attribute_not) -        << "an NSString" << IdxExpr->getSourceRange(); +        << "an NSString" << IdxExpr->getSourceRange() +        << getFunctionOrMethodParamRange(D, ArgIdx);        return;      }    } else if (!Ty->isPointerType() ||               !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { -    // FIXME: Should highlight the actual expression that has the wrong type.      S.Diag(Attr.getLoc(), diag::err_format_attribute_not) -      << "a string type" << IdxExpr->getSourceRange(); +      << "a string type" << IdxExpr->getSourceRange() +      << getFunctionOrMethodParamRange(D, ArgIdx);      return;    } @@ -2679,6 +2761,58 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {                            Attr.getAttributeSpellingListIndex()));  } +static void handleAlignValueAttr(Sema &S, Decl *D, +                                 const AttributeList &Attr) { +  S.AddAlignValueAttr(Attr.getRange(), D, Attr.getArgAsExpr(0), +                      Attr.getAttributeSpellingListIndex()); +} + +void Sema::AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, +                             unsigned SpellingListIndex) { +  AlignValueAttr TmpAttr(AttrRange, Context, E, SpellingListIndex); +  SourceLocation AttrLoc = AttrRange.getBegin(); + +  QualType T; +  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) +    T = TD->getUnderlyingType(); +  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) +    T = VD->getType(); +  else +    llvm_unreachable("Unknown decl type for align_value"); + +  if (!T->isDependentType() && !T->isAnyPointerType() && +      !T->isReferenceType() && !T->isMemberPointerType()) { +    Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only) +      << &TmpAttr /*TmpAttr.getName()*/ << T << D->getSourceRange(); +    return; +  } + +  if (!E->isValueDependent()) { +    llvm::APSInt Alignment(32); +    ExprResult ICE +      = VerifyIntegerConstantExpression(E, &Alignment, +          diag::err_align_value_attribute_argument_not_int, +            /*AllowFold*/ false); +    if (ICE.isInvalid()) +      return; + +    if (!Alignment.isPowerOf2()) { +      Diag(AttrLoc, diag::err_alignment_not_power_of_two) +        << E->getSourceRange(); +      return; +    } + +    D->addAttr(::new (Context) +               AlignValueAttr(AttrRange, Context, ICE.get(), +               SpellingListIndex)); +    return; +  } + +  // Save dependent expressions in the AST to be instantiated. +  D->addAttr(::new (Context) AlignValueAttr(TmpAttr)); +  return; +} +  static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {    // check the attribute arguments.    if (Attr.getNumArgs() > 1) { @@ -2773,7 +2907,7 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,    //   An alignment specification of zero has no effect.    if (!(TmpAttr.isAlignas() && !Alignment) &&        !llvm::isPowerOf2_64(Alignment.getZExtValue())) { -    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) +    Diag(AttrLoc, diag::err_alignment_not_power_of_two)        << E->getSourceRange();      return;    } @@ -3006,24 +3140,75 @@ static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {                           Attr.getAttributeSpellingListIndex()));  } +AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D, SourceRange Range, +                                              IdentifierInfo *Ident, +                                              unsigned AttrSpellingListIndex) { +  if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) { +    Diag(Range.getBegin(), diag::warn_attribute_ignored) << Ident; +    Diag(Optnone->getLocation(), diag::note_conflicting_attribute); +    return nullptr; +  } + +  if (D->hasAttr<AlwaysInlineAttr>()) +    return nullptr; + +  return ::new (Context) AlwaysInlineAttr(Range, Context, +                                          AttrSpellingListIndex); +} + +MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range, +                                    unsigned AttrSpellingListIndex) { +  if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) { +    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'minsize'"; +    Diag(Optnone->getLocation(), diag::note_conflicting_attribute); +    return nullptr; +  } + +  if (D->hasAttr<MinSizeAttr>()) +    return nullptr; + +  return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex); +} + +OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range, +                                              unsigned AttrSpellingListIndex) { +  if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) { +    Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline; +    Diag(Range.getBegin(), diag::note_conflicting_attribute); +    D->dropAttr<AlwaysInlineAttr>(); +  } +  if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) { +    Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize; +    Diag(Range.getBegin(), diag::note_conflicting_attribute); +    D->dropAttr<MinSizeAttr>(); +  } + +  if (D->hasAttr<OptimizeNoneAttr>()) +    return nullptr; + +  return ::new (Context) OptimizeNoneAttr(Range, Context, +                                          AttrSpellingListIndex); +} +  static void handleAlwaysInlineAttr(Sema &S, Decl *D,                                     const AttributeList &Attr) { -  if (checkAttrMutualExclusion<OptimizeNoneAttr>(S, D, Attr)) -    return; +  if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr( +          D, Attr.getRange(), Attr.getName(), +          Attr.getAttributeSpellingListIndex())) +    D->addAttr(Inline); +} -  D->addAttr(::new (S.Context) -             AlwaysInlineAttr(Attr.getRange(), S.Context, -                              Attr.getAttributeSpellingListIndex())); +static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { +  if (MinSizeAttr *MinSize = S.mergeMinSizeAttr( +          D, Attr.getRange(), Attr.getAttributeSpellingListIndex())) +    D->addAttr(MinSize);  }  static void handleOptimizeNoneAttr(Sema &S, Decl *D,                                     const AttributeList &Attr) { -  if (checkAttrMutualExclusion<AlwaysInlineAttr>(S, D, Attr)) -    return; - -  D->addAttr(::new (S.Context) -             OptimizeNoneAttr(Attr.getRange(), S.Context, -                              Attr.getAttributeSpellingListIndex())); +  if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr( +          D, Attr.getRange(), Attr.getAttributeSpellingListIndex())) +    D->addAttr(Optnone);  }  static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -3039,7 +3224,7 @@ static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {    D->addAttr(::new (S.Context)                CUDAGlobalAttr(Attr.getRange(), S.Context, -                            Attr.getAttributeSpellingListIndex())); +                             Attr.getAttributeSpellingListIndex()));  }  static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -3096,6 +3281,11 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {                 PascalAttr(Attr.getRange(), S.Context,                            Attr.getAttributeSpellingListIndex()));      return; +  case AttributeList::AT_VectorCall: +    D->addAttr(::new (S.Context) +               VectorCallAttr(Attr.getRange(), S.Context, +                              Attr.getAttributeSpellingListIndex())); +    return;    case AttributeList::AT_MSABI:      D->addAttr(::new (S.Context)                 MSABIAttr(Attr.getRange(), S.Context, @@ -3158,6 +3348,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,    case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;    case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;    case AttributeList::AT_Pascal: CC = CC_X86Pascal; break; +  case AttributeList::AT_VectorCall: CC = CC_X86VectorCall; break;    case AttributeList::AT_MSABI:      CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :                                                               CC_X86_64Win64; @@ -3242,14 +3433,6 @@ bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {  static void handleLaunchBoundsAttr(Sema &S, Decl *D,                                     const AttributeList &Attr) { -  // check the attribute arguments. -  if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { -    // FIXME: 0 is not okay. -    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) -      << Attr.getName() << 2; -    return; -  } -    uint32_t MaxThreads, MinBlocks = 0;    if (!checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), MaxThreads, 1))      return; @@ -3440,29 +3623,24 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,      default:        llvm_unreachable("invalid ownership attribute");      case AttributeList::AT_NSReturnsAutoreleased: -      D->addAttr(::new (S.Context) -                 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context, -                                           Attr.getAttributeSpellingListIndex())); +      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr( +          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));        return;      case AttributeList::AT_CFReturnsNotRetained: -      D->addAttr(::new (S.Context) -                 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context, -                                          Attr.getAttributeSpellingListIndex())); +      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr( +          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));        return;      case AttributeList::AT_NSReturnsNotRetained: -      D->addAttr(::new (S.Context) -                 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context, -                                          Attr.getAttributeSpellingListIndex())); +      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr( +          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));        return;      case AttributeList::AT_CFReturnsRetained: -      D->addAttr(::new (S.Context) -                 CFReturnsRetainedAttr(Attr.getRange(), S.Context, -                                       Attr.getAttributeSpellingListIndex())); +      D->addAttr(::new (S.Context) CFReturnsRetainedAttr( +          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));        return;      case AttributeList::AT_NSReturnsRetained: -      D->addAttr(::new (S.Context) -                 NSReturnsRetainedAttr(Attr.getRange(), S.Context, -                                       Attr.getAttributeSpellingListIndex())); +      D->addAttr(::new (S.Context) NSReturnsRetainedAttr( +          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));        return;    };  } @@ -3491,9 +3669,8 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,      return;    } -  D->addAttr(::new (S.Context) -                  ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context, -                                              attr.getAttributeSpellingListIndex())); +  D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr( +      attr.getRange(), S.Context, attr.getAttributeSpellingListIndex()));  }  static void handleObjCRequiresSuperAttr(Sema &S, Decl *D, @@ -3587,7 +3764,8 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D,  static void handleObjCDesignatedInitializer(Sema &S, Decl *D,                                              const AttributeList &Attr) {    ObjCInterfaceDecl *IFace; -  if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) +  if (ObjCCategoryDecl *CatDecl = +          dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))      IFace = CatDecl->getClassInterface();    else      IFace = cast<ObjCInterfaceDecl>(D->getDeclContext()); @@ -3812,6 +3990,32 @@ static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {      handleARMInterruptAttr(S, D, Attr);  } +static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, +                                    const AttributeList &Attr) { +  uint32_t NumRegs; +  Expr *NumRegsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); +  if (!checkUInt32Argument(S, Attr, NumRegsExpr, NumRegs)) +    return; + +  D->addAttr(::new (S.Context) +             AMDGPUNumVGPRAttr(Attr.getLoc(), S.Context, +                               NumRegs, +                               Attr.getAttributeSpellingListIndex())); +} + +static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, +                                    const AttributeList &Attr) { +  uint32_t NumRegs; +  Expr *NumRegsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); +  if (!checkUInt32Argument(S, Attr, NumRegsExpr, NumRegs)) +    return; + +  D->addAttr(::new (S.Context) +             AMDGPUNumSGPRAttr(Attr.getLoc(), S.Context, +                               NumRegs, +                               Attr.getAttributeSpellingListIndex())); +} +  static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,                                                const AttributeList& Attr) {    // If we try to apply it to a function pointer, don't warn, but don't @@ -3871,6 +4075,16 @@ static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {      return;    } +  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { +    if (FD->isInlined() && A.getKind() == AttributeList::AT_DLLImport && +        !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { +      // MinGW doesn't allow dllimport on inline functions. +      S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline) +          << A.getName(); +      return; +    } +  } +    unsigned Index = A.getAttributeSpellingListIndex();    Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport                        ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index) @@ -4001,6 +4215,19 @@ static void handleRequiresCapabilityAttr(Sema &S, Decl *D,    D->addAttr(RCA);  } +static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { +  if (auto *NSD = dyn_cast<NamespaceDecl>(D)) { +    if (NSD->isAnonymousNamespace()) { +      S.Diag(Attr.getLoc(), diag::warn_deprecated_anonymous_namespace); +      // Do not want to attach the attribute to the namespace because that will +      // cause confusing diagnostic reports for uses of declarations within the +      // namespace. +      return; +    } +  } +  handleAttrWithMessage<DeprecatedAttr>(S, D, Attr); +} +  /// Handles semantic checking for features that are common to all attributes,  /// such as checking whether a parameter was properly specified, or the correct  /// number of arguments were passed, etc. @@ -4020,11 +4247,20 @@ static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,    if (!Attr.diagnoseLangOpts(S))      return true; -  // If there are no optional arguments, then checking for the argument count -  // is trivial. -  if (Attr.getMinArgs() == Attr.getMaxArgs() && -      !checkAttributeNumArgs(S, Attr, Attr.getMinArgs())) -    return true; +  if (Attr.getMinArgs() == Attr.getMaxArgs()) { +    // If there are no optional arguments, then checking for the argument count +    // is trivial. +    if (!checkAttributeNumArgs(S, Attr, Attr.getMinArgs())) +      return true; +  } else { +    // There are optional arguments, so checking is slightly more involved. +    if (Attr.getMinArgs() && +        !checkAttributeAtLeastNumArgs(S, Attr, Attr.getMinArgs())) +      return true; +    else if (!Attr.hasVariadicArg() && Attr.getMaxArgs() && +             !checkAttributeAtMostNumArgs(S, Attr, Attr.getMaxArgs())) +      return true; +  }    // Check whether the attribute appertains to the given subject.    if (!Attr.diagnoseAppertainsTo(S, D)) @@ -4087,6 +4323,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_NoMips16:      handleSimpleAttribute<NoMips16Attr>(S, D, Attr);      break; +  case AttributeList::AT_AMDGPUNumVGPR: +    handleAMDGPUNumVGPRAttr(S, D, Attr); +    break; +  case AttributeList::AT_AMDGPUNumSGPR: +    handleAMDGPUNumSGPRAttr(S, D, Attr); +    break;    case AttributeList::AT_IBAction:      handleSimpleAttribute<IBActionAttr>(S, D, Attr);      break; @@ -4102,6 +4344,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_Aligned:      handleAlignedAttr(S, D, Attr);      break; +  case AttributeList::AT_AlignValue: +    handleAlignValueAttr(S, D, Attr); +    break;    case AttributeList::AT_AlwaysInline:      handleAlwaysInlineAttr(S, D, Attr);      break; @@ -4133,7 +4378,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,      handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);      break;    case AttributeList::AT_Deprecated: -    handleAttrWithMessage<DeprecatedAttr>(S, D, Attr); +    handleDeprecatedAttr(S, D, Attr);      break;    case AttributeList::AT_Destructor:      handleDestructorAttr(S, D, Attr); @@ -4145,11 +4390,14 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,      handleExtVectorTypeAttr(S, scope, D, Attr);      break;    case AttributeList::AT_MinSize: -    handleSimpleAttribute<MinSizeAttr>(S, D, Attr); +    handleMinSizeAttr(S, D, Attr);      break;    case AttributeList::AT_OptimizeNone:      handleOptimizeNoneAttr(S, D, Attr);      break; +  case AttributeList::AT_FlagEnum: +    handleSimpleAttribute<FlagEnumAttr>(S, D, Attr); +    break;    case AttributeList::AT_Flatten:      handleSimpleAttribute<FlattenAttr>(S, D, Attr);      break; @@ -4198,6 +4446,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_ReturnsNonNull:      handleReturnsNonNullAttr(S, D, Attr);      break; +  case AttributeList::AT_AssumeAligned: +    handleAssumeAlignedAttr(S, D, Attr); +    break;    case AttributeList::AT_Overloadable:      handleSimpleAttribute<OverloadableAttr>(S, D, Attr);      break; @@ -4392,6 +4643,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_FastCall:    case AttributeList::AT_ThisCall:    case AttributeList::AT_Pascal: +  case AttributeList::AT_VectorCall:    case AttributeList::AT_MSABI:    case AttributeList::AT_SysVABI:    case AttributeList::AT_Pcs: @@ -4553,19 +4805,31 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,      return;    } +  // FIXME: We should be able to handle this in TableGen as well. It would be +  // good to have a way to specify "these attributes must appear as a group", +  // for these. Additionally, it would be good to have a way to specify "these +  // attribute must never appear as a group" for attributes like cold and hot.    if (!D->hasAttr<OpenCLKernelAttr>()) {      // These attributes cannot be applied to a non-kernel function.      if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) { +      // FIXME: This emits a different error message than +      // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.        Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;        D->setInvalidDecl(); -    } -    if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) { +    } else if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) {        Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;        D->setInvalidDecl(); -    } -    if (Attr *A = D->getAttr<VecTypeHintAttr>()) { +    } else if (Attr *A = D->getAttr<VecTypeHintAttr>()) {        Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;        D->setInvalidDecl(); +    } else if (Attr *A = D->getAttr<AMDGPUNumVGPRAttr>()) { +      Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) +        << A << ExpectedKernelFunction; +      D->setInvalidDecl(); +    } else if (Attr *A = D->getAttr<AMDGPUNumSGPRAttr>()) { +      Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) +        << A << ExpectedKernelFunction; +      D->setInvalidDecl();      }    }  } @@ -4576,7 +4840,7 @@ bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,                                            const AttributeList *AttrList) {    for (const AttributeList* l = AttrList; l; l = l->getNext()) {      if (l->getKind() == AttributeList::AT_Annotate) { -      handleAnnotateAttr(*this, ASDecl, *l); +      ProcessDeclAttribute(*this, nullptr, ASDecl, *l, l->isCXX11Attribute());      } else {        Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);        return true; @@ -4774,61 +5038,6 @@ static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,    diag.Triggered = true;  } -void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { -  assert(DelayedDiagnostics.getCurrentPool()); -  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); -  DelayedDiagnostics.popWithoutEmitting(state); - -  // When delaying diagnostics to run in the context of a parsed -  // declaration, we only want to actually emit anything if parsing -  // succeeds. -  if (!decl) return; - -  // We emit all the active diagnostics in this pool or any of its -  // parents.  In general, we'll get one pool for the decl spec -  // and a child pool for each declarator; in a decl group like: -  //   deprecated_typedef foo, *bar, baz(); -  // only the declarator pops will be passed decls.  This is correct; -  // we really do need to consider delayed diagnostics from the decl spec -  // for each of the different declarations. -  const DelayedDiagnosticPool *pool = &poppedPool; -  do { -    for (DelayedDiagnosticPool::pool_iterator -           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { -      // This const_cast is a bit lame.  Really, Triggered should be mutable. -      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); -      if (diag.Triggered) -        continue; - -      switch (diag.Kind) { -      case DelayedDiagnostic::Deprecation: -      case DelayedDiagnostic::Unavailable: -        // Don't bother giving deprecation/unavailable diagnostics if -        // the decl is invalid. -        if (!decl->isInvalidDecl()) -          HandleDelayedAvailabilityCheck(diag, decl); -        break; - -      case DelayedDiagnostic::Access: -        HandleDelayedAccessCheck(diag, decl); -        break; - -      case DelayedDiagnostic::ForbiddenType: -        handleDelayedForbiddenType(*this, diag, decl); -        break; -      } -    } -  } while ((pool = pool->getParent())); -} - -/// Given a set of delayed diagnostics, re-emit them as if they had -/// been delayed in the current context instead of in the given pool. -/// Essentially, this just moves them to the current pool. -void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { -  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); -  assert(curPool && "re-emitting in undelayed context not supported"); -  curPool->steal(pool); -}  static bool isDeclDeprecated(Decl *D) {    do { @@ -4852,17 +5061,12 @@ static bool isDeclUnavailable(Decl *D) {    return false;  } -static void -DoEmitAvailabilityWarning(Sema &S, -                          DelayedDiagnostic::DDKind K, -                          Decl *Ctx, -                          const NamedDecl *D, -                          StringRef Message, -                          SourceLocation Loc, -                          const ObjCInterfaceDecl *UnknownObjCClass, -                          const ObjCPropertyDecl *ObjCProperty, -                          bool ObjCPropertyAccess) { - +static void DoEmitAvailabilityWarning(Sema &S, DelayedDiagnostic::DDKind K, +                                      Decl *Ctx, const NamedDecl *D, +                                      StringRef Message, SourceLocation Loc, +                                      const ObjCInterfaceDecl *UnknownObjCClass, +                                      const ObjCPropertyDecl *ObjCProperty, +                                      bool ObjCPropertyAccess) {    // Diagnostics for deprecated or unavailable.    unsigned diag, diag_message, diag_fwdclass_message; @@ -4874,65 +5078,116 @@ DoEmitAvailabilityWarning(Sema &S,    // Don't warn if our current context is deprecated or unavailable.    switch (K) { -    case DelayedDiagnostic::Deprecation: -      if (isDeclDeprecated(Ctx)) -        return; -      diag = !ObjCPropertyAccess ? diag::warn_deprecated -                                 : diag::warn_property_method_deprecated; -      diag_message = diag::warn_deprecated_message; -      diag_fwdclass_message = diag::warn_deprecated_fwdclass_message; -      property_note_select = /* deprecated */ 0; -      available_here_select_kind = /* deprecated */ 2; -      break; +  case DelayedDiagnostic::Deprecation: +    if (isDeclDeprecated(Ctx)) +      return; +    diag = !ObjCPropertyAccess ? diag::warn_deprecated +                               : diag::warn_property_method_deprecated; +    diag_message = diag::warn_deprecated_message; +    diag_fwdclass_message = diag::warn_deprecated_fwdclass_message; +    property_note_select = /* deprecated */ 0; +    available_here_select_kind = /* deprecated */ 2; +    break; -    case DelayedDiagnostic::Unavailable: -      if (isDeclUnavailable(Ctx)) -        return; -      diag = !ObjCPropertyAccess ? diag::err_unavailable -                                 : diag::err_property_method_unavailable; -      diag_message = diag::err_unavailable_message; -      diag_fwdclass_message = diag::warn_unavailable_fwdclass_message; -      property_note_select = /* unavailable */ 1; -      available_here_select_kind = /* unavailable */ 0; -      break; +  case DelayedDiagnostic::Unavailable: +    if (isDeclUnavailable(Ctx)) +      return; +    diag = !ObjCPropertyAccess ? diag::err_unavailable +                               : diag::err_property_method_unavailable; +    diag_message = diag::err_unavailable_message; +    diag_fwdclass_message = diag::warn_unavailable_fwdclass_message; +    property_note_select = /* unavailable */ 1; +    available_here_select_kind = /* unavailable */ 0; +    break; -    default: -      llvm_unreachable("Neither a deprecation or unavailable kind"); +  default: +    llvm_unreachable("Neither a deprecation or unavailable kind");    } -  DeclarationName Name = D->getDeclName();    if (!Message.empty()) { -    S.Diag(Loc, diag_message) << Name << Message; +    S.Diag(Loc, diag_message) << D << Message;      if (ObjCProperty)        S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) -        << ObjCProperty->getDeclName() << property_note_select; +          << ObjCProperty->getDeclName() << property_note_select;    } else if (!UnknownObjCClass) { -    S.Diag(Loc, diag) << Name; +    S.Diag(Loc, diag) << D;      if (ObjCProperty)        S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) -        << ObjCProperty->getDeclName() << property_note_select; +          << ObjCProperty->getDeclName() << property_note_select;    } else { -    S.Diag(Loc, diag_fwdclass_message) << Name; +    S.Diag(Loc, diag_fwdclass_message) << D;      S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);    }    S.Diag(D->getLocation(), diag::note_availability_specified_here) -    << D << available_here_select_kind; +      << D << available_here_select_kind;  } -void Sema::HandleDelayedAvailabilityCheck(DelayedDiagnostic &DD, -                                          Decl *Ctx) { +static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD, +                                           Decl *Ctx) {    DD.Triggered = true; -  DoEmitAvailabilityWarning(*this, -                            (DelayedDiagnostic::DDKind) DD.Kind, -                            Ctx, -                            DD.getDeprecationDecl(), -                            DD.getDeprecationMessage(), -                            DD.Loc, -                            DD.getUnknownObjCClass(), +  DoEmitAvailabilityWarning(S, (DelayedDiagnostic::DDKind)DD.Kind, Ctx, +                            DD.getDeprecationDecl(), DD.getDeprecationMessage(), +                            DD.Loc, DD.getUnknownObjCClass(),                              DD.getObjCProperty(), false);  } +void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { +  assert(DelayedDiagnostics.getCurrentPool()); +  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); +  DelayedDiagnostics.popWithoutEmitting(state); + +  // When delaying diagnostics to run in the context of a parsed +  // declaration, we only want to actually emit anything if parsing +  // succeeds. +  if (!decl) return; + +  // We emit all the active diagnostics in this pool or any of its +  // parents.  In general, we'll get one pool for the decl spec +  // and a child pool for each declarator; in a decl group like: +  //   deprecated_typedef foo, *bar, baz(); +  // only the declarator pops will be passed decls.  This is correct; +  // we really do need to consider delayed diagnostics from the decl spec +  // for each of the different declarations. +  const DelayedDiagnosticPool *pool = &poppedPool; +  do { +    for (DelayedDiagnosticPool::pool_iterator +           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { +      // This const_cast is a bit lame.  Really, Triggered should be mutable. +      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); +      if (diag.Triggered) +        continue; + +      switch (diag.Kind) { +      case DelayedDiagnostic::Deprecation: +      case DelayedDiagnostic::Unavailable: +        // Don't bother giving deprecation/unavailable diagnostics if +        // the decl is invalid. +        if (!decl->isInvalidDecl()) +          handleDelayedAvailabilityCheck(*this, diag, decl); +        break; + +      case DelayedDiagnostic::Access: +        HandleDelayedAccessCheck(diag, decl); +        break; + +      case DelayedDiagnostic::ForbiddenType: +        handleDelayedForbiddenType(*this, diag, decl); +        break; +      } +    } +  } while ((pool = pool->getParent())); +} + +/// Given a set of delayed diagnostics, re-emit them as if they had +/// been delayed in the current context instead of in the given pool. +/// Essentially, this just moves them to the current pool. +void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { +  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); +  assert(curPool && "re-emitting in undelayed context not supported"); +  curPool->steal(pool); +} +  void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,                                     NamedDecl *D, StringRef Message,                                     SourceLocation Loc, @@ -4941,11 +5196,9 @@ void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,                                     bool ObjCPropertyAccess) {    // Delay if we're currently parsing a declaration.    if (DelayedDiagnostics.shouldDelayDiagnostics()) { -    DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D, -                                                               UnknownObjCClass, -                                                               ObjCProperty, -                                                               Message, -                                                               ObjCPropertyAccess)); +    DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability( +        AD, Loc, D, UnknownObjCClass, ObjCProperty, Message, +        ObjCPropertyAccess));      return;    } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c5cd83da59d6..510738ea8168 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -36,6 +36,7 @@  #include "clang/Sema/ParsedTemplate.h"  #include "clang/Sema/Scope.h"  #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/Template.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/SmallString.h"  #include <map> @@ -212,7 +213,7 @@ Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,    ComputedEST = EST_Dynamic;    // Record the exceptions in this function's exception specification.    for (const auto &E : Proto->exceptions()) -    if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E))) +    if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E)).second)        Exceptions.push_back(E);  } @@ -353,7 +354,9 @@ void Sema::ActOnParamDefaultArgumentError(Decl *param,    Param->setInvalidDecl();    UnparsedDefaultArgLocs.erase(Param);    Param->setDefaultArg(new(Context) -                       OpaqueValueExpr(EqualLoc, Param->getType(), VK_RValue)); +                       OpaqueValueExpr(EqualLoc, +                                       Param->getType().getNonReferenceType(), +                                       VK_RValue));  }  /// CheckExtraCXXDefaultArguments - Check for any extra default @@ -385,9 +388,14 @@ void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {          ParmVarDecl *Param = cast<ParmVarDecl>(chunk.Fun.Params[argIdx].Param);          if (Param->hasUnparsedDefaultArg()) {            CachedTokens *Toks = chunk.Fun.Params[argIdx].DefaultArgTokens; +          SourceRange SR; +          if (Toks->size() > 1) +            SR = SourceRange((*Toks)[1].getLocation(), +                             Toks->back().getLocation()); +          else +            SR = UnparsedDefaultArgLocs[Param];            Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc) -            << SourceRange((*Toks)[1].getLocation(), -                           Toks->back().getLocation()); +            << SR;            delete Toks;            chunk.Fun.Params[argIdx].DefaultArgTokens = nullptr;          } else if (Param->getDefaultArg()) { @@ -446,20 +454,24 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,      bool OldParamHasDfl = OldParam->hasDefaultArg();      bool NewParamHasDfl = NewParam->hasDefaultArg(); -    NamedDecl *ND = Old; -      // The declaration context corresponding to the scope is the semantic      // parent, unless this is a local function declaration, in which case      // it is that surrounding function. -    DeclContext *ScopeDC = New->getLexicalDeclContext(); -    if (!ScopeDC->isFunctionOrMethod()) -      ScopeDC = New->getDeclContext(); -    if (S && !isDeclInScope(ND, ScopeDC, S) && +    DeclContext *ScopeDC = New->isLocalExternDecl() +                               ? New->getLexicalDeclContext() +                               : New->getDeclContext(); +    if (S && !isDeclInScope(Old, ScopeDC, S) &&          !New->getDeclContext()->isRecord())        // Ignore default parameters of old decl if they are not in        // the same scope and this is not an out-of-line definition of        // a member function.        OldParamHasDfl = false; +    if (New->isLocalExternDecl() != Old->isLocalExternDecl()) +      // If only one of these is a local function declaration, then they are +      // declared in different scopes, even though isDeclInScope may think +      // they're in the same scope. (If both are local, the scope check is +      // sufficent, and if neither is local, then they are in the same scope.) +      OldParamHasDfl = false;      if (OldParamHasDfl && NewParamHasDfl) { @@ -855,7 +867,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,        // C++1y allows types to be defined, not just declared.        if (cast<TagDecl>(DclIt)->isThisDeclarationADefinition())          SemaRef.Diag(DS->getLocStart(), -                     SemaRef.getLangOpts().CPlusPlus1y +                     SemaRef.getLangOpts().CPlusPlus14                         ? diag::warn_cxx11_compat_constexpr_type_definition                         : diag::ext_constexpr_type_definition)            << isa<CXXConstructorDecl>(Dcl); @@ -896,7 +908,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,          }        }        SemaRef.Diag(VD->getLocation(), -                   SemaRef.getLangOpts().CPlusPlus1y +                   SemaRef.getLangOpts().CPlusPlus14                      ? diag::warn_cxx11_compat_constexpr_local_var                      : diag::ext_constexpr_local_var)          << isa<CXXConstructorDecl>(Dcl); @@ -1041,7 +1053,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,    case Stmt::ContinueStmtClass:      // C++1y allows all of these. We don't allow them as extensions in C++11,      // because they don't make sense without variable mutation. -    if (!SemaRef.getLangOpts().CPlusPlus1y) +    if (!SemaRef.getLangOpts().CPlusPlus14)        break;      if (!Cxx1yLoc.isValid())        Cxx1yLoc = S->getLocStart(); @@ -1115,7 +1127,7 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {    if (Cxx1yLoc.isValid())      Diag(Cxx1yLoc, -         getLangOpts().CPlusPlus1y +         getLangOpts().CPlusPlus14             ? diag::warn_cxx11_compat_constexpr_body_invalid_stmt             : diag::ext_constexpr_body_invalid_stmt)        << isa<CXXConstructorDecl>(Dcl); @@ -1180,7 +1192,7 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {        // statement. We still do, unless the return type might be void, because        // otherwise if there's no return statement, the function cannot        // be used in a core constant expression. -      bool OK = getLangOpts().CPlusPlus1y && +      bool OK = getLangOpts().CPlusPlus14 &&                  (Dcl->getReturnType()->isVoidType() ||                   Dcl->getReturnType()->isDependentType());        Diag(Dcl->getLocation(), @@ -1190,7 +1202,7 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {      }      if (ReturnStmts.size() > 1) {        Diag(ReturnStmts.back(), -           getLangOpts().CPlusPlus1y +           getLangOpts().CPlusPlus14               ? diag::warn_cxx11_compat_constexpr_body_multiple_return               : diag::ext_constexpr_body_multiple_return);        for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I) @@ -1881,7 +1893,7 @@ void Sema::CheckOverrideControl(NamedDecl *D) {    }    // C++11 [class.virtual]p5: -  //   If a virtual function is marked with the virt-specifier override and +  //   If a function is marked with the virt-specifier override and    //   does not override a member function of a base class, the program is    //   ill-formed.    bool HasOverriddenMethods = @@ -1891,6 +1903,30 @@ void Sema::CheckOverrideControl(NamedDecl *D) {        << MD->getDeclName();  } +void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) { +  if (D->isInvalidDecl() || D->hasAttr<OverrideAttr>()) +    return; +  CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D); +  if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>() || +      isa<CXXDestructorDecl>(MD)) +    return; + +  SourceLocation Loc = MD->getLocation(); +  SourceLocation SpellingLoc = Loc; +  if (getSourceManager().isMacroArgExpansion(Loc)) +    SpellingLoc = getSourceManager().getImmediateExpansionRange(Loc).first; +  SpellingLoc = getSourceManager().getSpellingLoc(SpellingLoc); +  if (SpellingLoc.isValid() && getSourceManager().isInSystemHeader(SpellingLoc)) +      return; +     +  if (MD->size_overridden_methods() > 0) { +    Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding) +      << MD->getDeclName(); +    const CXXMethodDecl *OMD = *MD->begin_overridden_methods(); +    Diag(OMD->getLocation(), diag::note_overridden_virtual_function); +  } +} +  /// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member  /// function overrides a virtual member function marked 'final', according to  /// C++11 [class.virtual]p4. @@ -2133,7 +2169,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,      if (BitWidth) {        if (Member->isInvalidDecl()) {          // don't emit another diagnostic. -      } else if (isa<VarDecl>(Member)) { +      } else if (isa<VarDecl>(Member) || isa<VarTemplateDecl>(Member)) {          // C++ 9.6p3: A bit-field shall not be a static member.          // "static member 'A' cannot be a bit-field"          Diag(Loc, diag::err_static_not_bitfield) @@ -2205,18 +2241,73 @@ namespace {      Sema &S;      // List of Decls to generate a warning on.  Also remove Decls that become      // initialized. -    llvm::SmallPtrSet<ValueDecl*, 4> &Decls; +    llvm::SmallPtrSetImpl<ValueDecl*> &Decls; +    // List of base classes of the record.  Classes are removed after their +    // initializers. +    llvm::SmallPtrSetImpl<QualType> &BaseClasses; +    // Vector of decls to be removed from the Decl set prior to visiting the +    // nodes.  These Decls may have been initialized in the prior initializer. +    llvm::SmallVector<ValueDecl*, 4> DeclsToRemove;      // If non-null, add a note to the warning pointing back to the constructor.      const CXXConstructorDecl *Constructor; +    // Variables to hold state when processing an initializer list.  When +    // InitList is true, special case initialization of FieldDecls matching +    // InitListFieldDecl. +    bool InitList; +    FieldDecl *InitListFieldDecl; +    llvm::SmallVector<unsigned, 4> InitFieldIndex; +    public:      typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited;      UninitializedFieldVisitor(Sema &S, -                              llvm::SmallPtrSet<ValueDecl*, 4> &Decls, -                              const CXXConstructorDecl *Constructor) -      : Inherited(S.Context), S(S), Decls(Decls), -        Constructor(Constructor) { } +                              llvm::SmallPtrSetImpl<ValueDecl*> &Decls, +                              llvm::SmallPtrSetImpl<QualType> &BaseClasses) +      : Inherited(S.Context), S(S), Decls(Decls), BaseClasses(BaseClasses), +        Constructor(nullptr), InitList(false), InitListFieldDecl(nullptr) {} + +    // Returns true if the use of ME is not an uninitialized use. +    bool IsInitListMemberExprInitialized(MemberExpr *ME, +                                         bool CheckReferenceOnly) { +      llvm::SmallVector<FieldDecl*, 4> Fields; +      bool ReferenceField = false; +      while (ME) { +        FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); +        if (!FD) +          return false; +        Fields.push_back(FD); +        if (FD->getType()->isReferenceType()) +          ReferenceField = true; +        ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParenImpCasts()); +      } + +      // Binding a reference to an unintialized field is not an +      // uninitialized use. +      if (CheckReferenceOnly && !ReferenceField) +        return true; -    void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly) { +      llvm::SmallVector<unsigned, 4> UsedFieldIndex; +      // Discard the first field since it is the field decl that is being +      // initialized. +      for (auto I = Fields.rbegin() + 1, E = Fields.rend(); I != E; ++I) { +        UsedFieldIndex.push_back((*I)->getFieldIndex()); +      } + +      for (auto UsedIter = UsedFieldIndex.begin(), +                UsedEnd = UsedFieldIndex.end(), +                OrigIter = InitFieldIndex.begin(), +                OrigEnd = InitFieldIndex.end(); +           UsedIter != UsedEnd && OrigIter != OrigEnd; ++UsedIter, ++OrigIter) { +        if (*UsedIter < *OrigIter) +          return true; +        if (*UsedIter > *OrigIter) +          break; +      } + +      return false; +    } + +    void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly, +                          bool AddressOf) {        if (isa<EnumConstantDecl>(ME->getMemberDecl()))          return; @@ -2224,33 +2315,63 @@ namespace {        // or union.        MemberExpr *FieldME = ME; +      bool AllPODFields = FieldME->getType().isPODType(S.Context); +        Expr *Base = ME; -      while (isa<MemberExpr>(Base)) { -        ME = cast<MemberExpr>(Base); +      while (MemberExpr *SubME = +                 dyn_cast<MemberExpr>(Base->IgnoreParenImpCasts())) { -        if (isa<VarDecl>(ME->getMemberDecl())) +        if (isa<VarDecl>(SubME->getMemberDecl()))            return; -        if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) +        if (FieldDecl *FD = dyn_cast<FieldDecl>(SubME->getMemberDecl()))            if (!FD->isAnonymousStructOrUnion()) -            FieldME = ME; +            FieldME = SubME; + +        if (!FieldME->getType().isPODType(S.Context)) +          AllPODFields = false; -        Base = ME->getBase(); +        Base = SubME->getBase();        } -      if (!isa<CXXThisExpr>(Base)) +      if (!isa<CXXThisExpr>(Base->IgnoreParenImpCasts())) +        return; + +      if (AddressOf && AllPODFields)          return;        ValueDecl* FoundVD = FieldME->getMemberDecl(); +      if (ImplicitCastExpr *BaseCast = dyn_cast<ImplicitCastExpr>(Base)) { +        while (isa<ImplicitCastExpr>(BaseCast->getSubExpr())) { +          BaseCast = cast<ImplicitCastExpr>(BaseCast->getSubExpr()); +        } + +        if (BaseCast->getCastKind() == CK_UncheckedDerivedToBase) { +          QualType T = BaseCast->getType(); +          if (T->isPointerType() && +              BaseClasses.count(T->getPointeeType())) { +            S.Diag(FieldME->getExprLoc(), diag::warn_base_class_is_uninit) +                << T->getPointeeType() << FoundVD; +          } +        } +      } +        if (!Decls.count(FoundVD))          return;        const bool IsReference = FoundVD->getType()->isReferenceType(); -      // Prevent double warnings on use of unbounded references. -      if (IsReference != CheckReferenceOnly) -        return; +      if (InitList && !AddressOf && FoundVD == InitListFieldDecl) { +        // Special checking for initializer lists. +        if (IsInitListMemberExprInitialized(ME, CheckReferenceOnly)) { +          return; +        } +      } else { +        // Prevent double warnings on use of unbounded references. +        if (CheckReferenceOnly && !IsReference) +          return; +      }        unsigned diag = IsReference            ? diag::warn_reference_field_is_uninit @@ -2263,74 +2384,160 @@ namespace {      } -    void HandleValue(Expr *E) { +    void HandleValue(Expr *E, bool AddressOf) {        E = E->IgnoreParens();        if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { -        HandleMemberExpr(ME, false /*CheckReferenceOnly*/); +        HandleMemberExpr(ME, false /*CheckReferenceOnly*/, +                         AddressOf /*AddressOf*/);          return;        }        if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { -        HandleValue(CO->getTrueExpr()); -        HandleValue(CO->getFalseExpr()); +        Visit(CO->getCond()); +        HandleValue(CO->getTrueExpr(), AddressOf); +        HandleValue(CO->getFalseExpr(), AddressOf);          return;        }        if (BinaryConditionalOperator *BCO =                dyn_cast<BinaryConditionalOperator>(E)) { -        HandleValue(BCO->getCommon()); -        HandleValue(BCO->getFalseExpr()); +        Visit(BCO->getCond()); +        HandleValue(BCO->getFalseExpr(), AddressOf); +        return; +      } + +      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { +        HandleValue(OVE->getSourceExpr(), AddressOf);          return;        }        if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {          switch (BO->getOpcode()) {          default: -          return; +          break;          case(BO_PtrMemD):          case(BO_PtrMemI): -          HandleValue(BO->getLHS()); +          HandleValue(BO->getLHS(), AddressOf); +          Visit(BO->getRHS());            return;          case(BO_Comma): -          HandleValue(BO->getRHS()); +          Visit(BO->getLHS()); +          HandleValue(BO->getRHS(), AddressOf);            return;          }        } + +      Visit(E); +    } + +    void CheckInitListExpr(InitListExpr *ILE) { +      InitFieldIndex.push_back(0); +      for (auto Child : ILE->children()) { +        if (InitListExpr *SubList = dyn_cast<InitListExpr>(Child)) { +          CheckInitListExpr(SubList); +        } else { +          Visit(Child); +        } +        ++InitFieldIndex.back(); +      } +      InitFieldIndex.pop_back(); +    } + +    void CheckInitializer(Expr *E, const CXXConstructorDecl *FieldConstructor, +                          FieldDecl *Field, const Type *BaseClass) { +      // Remove Decls that may have been initialized in the previous +      // initializer. +      for (ValueDecl* VD : DeclsToRemove) +        Decls.erase(VD); +      DeclsToRemove.clear(); + +      Constructor = FieldConstructor; +      InitListExpr *ILE = dyn_cast<InitListExpr>(E); + +      if (ILE && Field) { +        InitList = true; +        InitListFieldDecl = Field; +        InitFieldIndex.clear(); +        CheckInitListExpr(ILE); +      } else { +        InitList = false; +        Visit(E); +      } + +      if (Field) +        Decls.erase(Field); +      if (BaseClass) +        BaseClasses.erase(BaseClass->getCanonicalTypeInternal());      }      void VisitMemberExpr(MemberExpr *ME) {        // All uses of unbounded reference fields will warn. -      HandleMemberExpr(ME, true /*CheckReferenceOnly*/); - -      Inherited::VisitMemberExpr(ME); +      HandleMemberExpr(ME, true /*CheckReferenceOnly*/, false /*AddressOf*/);      }      void VisitImplicitCastExpr(ImplicitCastExpr *E) { -      if (E->getCastKind() == CK_LValueToRValue) -        HandleValue(E->getSubExpr()); +      if (E->getCastKind() == CK_LValueToRValue) { +        HandleValue(E->getSubExpr(), false /*AddressOf*/); +        return; +      }        Inherited::VisitImplicitCastExpr(E);      }      void VisitCXXConstructExpr(CXXConstructExpr *E) { -      if (E->getConstructor()->isCopyConstructor()) -        if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(E->getArg(0))) +      if (E->getConstructor()->isCopyConstructor()) { +        Expr *ArgExpr = E->getArg(0); +        if (InitListExpr *ILE = dyn_cast<InitListExpr>(ArgExpr)) +          if (ILE->getNumInits() == 1) +            ArgExpr = ILE->getInit(0); +        if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr))            if (ICE->getCastKind() == CK_NoOp) -            if (MemberExpr *ME = dyn_cast<MemberExpr>(ICE->getSubExpr())) -              HandleMemberExpr(ME, false /*CheckReferenceOnly*/); -       +            ArgExpr = ICE->getSubExpr(); +        HandleValue(ArgExpr, false /*AddressOf*/); +        return; +      }        Inherited::VisitCXXConstructExpr(E);      }      void VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {        Expr *Callee = E->getCallee(); -      if (isa<MemberExpr>(Callee)) -        HandleValue(Callee); +      if (isa<MemberExpr>(Callee)) { +        HandleValue(Callee, false /*AddressOf*/); +        for (auto Arg : E->arguments()) +          Visit(Arg); +        return; +      }        Inherited::VisitCXXMemberCallExpr(E);      } +    void VisitCallExpr(CallExpr *E) { +      // Treat std::move as a use. +      if (E->getNumArgs() == 1) { +        if (FunctionDecl *FD = E->getDirectCallee()) { +          if (FD->isInStdNamespace() && FD->getIdentifier() && +              FD->getIdentifier()->isStr("move")) { +            HandleValue(E->getArg(0), false /*AddressOf*/); +            return; +          } +        } +      } + +      Inherited::VisitCallExpr(E); +    } + +    void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { +      Expr *Callee = E->getCallee(); + +      if (isa<UnresolvedLookupExpr>(Callee)) +        return Inherited::VisitCXXOperatorCallExpr(E); + +      Visit(Callee); +      for (auto Arg : E->arguments()) +        HandleValue(Arg->IgnoreParenImpCasts(), false /*AddressOf*/); +    } +      void VisitBinaryOperator(BinaryOperator *E) {        // If a field assignment is detected, remove the field from the        // uninitiailized field set. @@ -2338,30 +2545,32 @@ namespace {          if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getLHS()))            if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))              if (!FD->getType()->isReferenceType()) -              Decls.erase(FD); +              DeclsToRemove.push_back(FD); + +      if (E->isCompoundAssignmentOp()) { +        HandleValue(E->getLHS(), false /*AddressOf*/); +        Visit(E->getRHS()); +        return; +      }        Inherited::VisitBinaryOperator(E);      } -  }; -  static void CheckInitExprContainsUninitializedFields( -      Sema &S, Expr *E, llvm::SmallPtrSet<ValueDecl*, 4> &Decls, -      const CXXConstructorDecl *Constructor) { -    if (Decls.size() == 0) -      return; - -    if (!E) -      return; -    if (CXXDefaultInitExpr *Default = dyn_cast<CXXDefaultInitExpr>(E)) { -      E = Default->getExpr(); -      if (!E) +    void VisitUnaryOperator(UnaryOperator *E) { +      if (E->isIncrementDecrementOp()) { +        HandleValue(E->getSubExpr(), false /*AddressOf*/);          return; -      // In class initializers will point to the constructor. -      UninitializedFieldVisitor(S, Decls, Constructor).Visit(E); -    } else { -      UninitializedFieldVisitor(S, Decls, nullptr).Visit(E); +      } +      if (E->getOpcode() == UO_AddrOf) { +        if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getSubExpr())) { +          HandleValue(ME->getBase(), true /*AddressOf*/); +          return; +        } +      } + +      Inherited::VisitUnaryOperator(E);      } -  } +  };    // Diagnose value-uses of fields to initialize themselves, e.g.    //   foo(foo) @@ -2382,6 +2591,9 @@ namespace {      const CXXRecordDecl *RD = Constructor->getParent(); +    if (RD->getDescribedClassTemplate()) +      return; +      // Holds fields that are uninitialized.      llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields; @@ -2394,14 +2606,39 @@ namespace {        }      } +    llvm::SmallPtrSet<QualType, 4> UninitializedBaseClasses; +    for (auto I : RD->bases()) +      UninitializedBaseClasses.insert(I.getType().getCanonicalType()); + +    if (UninitializedFields.empty() && UninitializedBaseClasses.empty()) +      return; + +    UninitializedFieldVisitor UninitializedChecker(SemaRef, +                                                   UninitializedFields, +                                                   UninitializedBaseClasses); +      for (const auto *FieldInit : Constructor->inits()) { -      Expr *InitExpr = FieldInit->getInit(); +      if (UninitializedFields.empty() && UninitializedBaseClasses.empty()) +        break; -      CheckInitExprContainsUninitializedFields( -          SemaRef, InitExpr, UninitializedFields, Constructor); +      Expr *InitExpr = FieldInit->getInit(); +      if (!InitExpr) +        continue; -      if (FieldDecl *Field = FieldInit->getAnyMember()) -        UninitializedFields.erase(Field); +      if (CXXDefaultInitExpr *Default = +              dyn_cast<CXXDefaultInitExpr>(InitExpr)) { +        InitExpr = Default->getExpr(); +        if (!InitExpr) +          continue; +        // In class initializers will point to the constructor. +        UninitializedChecker.CheckInitializer(InitExpr, Constructor, +                                              FieldInit->getAnyMember(), +                                              FieldInit->getBaseClass()); +      } else { +        UninitializedChecker.CheckInitializer(InitExpr, nullptr, +                                              FieldInit->getAnyMember(), +                                              FieldInit->getBaseClass()); +      }      }    }  } // namespace @@ -2424,13 +2661,14 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,    // Pop the notional constructor scope we created earlier.    PopFunctionScopeInfo(nullptr, D); -  FieldDecl *FD = cast<FieldDecl>(D); -  assert(FD->getInClassInitStyle() != ICIS_NoInit && +  FieldDecl *FD = dyn_cast<FieldDecl>(D); +  assert((isa<MSPropertyDecl>(D) || FD->getInClassInitStyle() != ICIS_NoInit) &&           "must set init style when field is created");    if (!InitExpr) { -    FD->setInvalidDecl(); -    FD->removeInClassInitializer(); +    D->setInvalidDecl(); +    if (FD) +      FD->removeInClassInitializer();      return;    } @@ -2581,6 +2819,11 @@ Sema::BuildMemInitializer(Decl *ConstructorD,                            SourceLocation IdLoc,                            Expr *Init,                            SourceLocation EllipsisLoc) { +  ExprResult Res = CorrectDelayedTyposInExpr(Init); +  if (!Res.isUsable()) +    return true; +  Init = Res.get(); +    if (!ConstructorD)      return true; @@ -2610,8 +2853,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD,    //   using a qualified name. ]    if (!SS.getScopeRep() && !TemplateTypeTy) {      // Look for a member, first. -    DeclContext::lookup_result Result -      = ClassDecl->lookup(MemberOrBase); +    DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase);      if (!Result.empty()) {        ValueDecl *Member;        if ((Member = dyn_cast<FieldDecl>(Result.front())) || @@ -2666,10 +2908,11 @@ Sema::BuildMemInitializer(Decl *ConstructorD,        // If no results were found, try to correct typos.        TypoCorrection Corr; -      MemInitializerValidatorCCC Validator(ClassDecl);        if (R.empty() && BaseType.isNull() && -          (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, -                              Validator, CTK_ErrorRecovery, ClassDecl))) { +          (Corr = CorrectTypo( +               R.getLookupNameInfo(), R.getLookupKind(), S, &SS, +               llvm::make_unique<MemInitializerValidatorCCC>(ClassDecl), +               CTK_ErrorRecovery, ClassDecl))) {          if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) {            // We have found a non-static data member with a similar            // name to what was typed; complain and initialize that @@ -2713,6 +2956,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD,      if (BaseType.isNull()) {        BaseType = Context.getTypeDeclType(TyD); +      MarkAnyDeclReferenced(TyD->getLocation(), TyD, /*OdrUse=*/false);        if (SS.isSet())          // FIXME: preserve source range information          BaseType = Context.getElaboratedType(ETK_None, SS.getScopeRep(), @@ -3528,19 +3772,19 @@ static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info,      return false;    if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) { -    Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, -                                           Info.Ctor->getLocation(), Field); +    ExprResult DIE = +        SemaRef.BuildCXXDefaultInitExpr(Info.Ctor->getLocation(), Field); +    if (DIE.isInvalid()) +      return true;      CXXCtorInitializer *Init;      if (Indirect) -      Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect, -                                                      SourceLocation(), -                                                      SourceLocation(), DIE, -                                                      SourceLocation()); +      Init = new (SemaRef.Context) +          CXXCtorInitializer(SemaRef.Context, Indirect, SourceLocation(), +                             SourceLocation(), DIE.get(), SourceLocation());      else -      Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field, -                                                      SourceLocation(), -                                                      SourceLocation(), DIE, -                                                      SourceLocation()); +      Init = new (SemaRef.Context) +          CXXCtorInitializer(SemaRef.Context, Field, SourceLocation(), +                             SourceLocation(), DIE.get(), SourceLocation());      return Info.addFieldInitializer(Init);    } @@ -3582,6 +3826,8 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,    DelegatingCtorDecls.push_back(Constructor); +  DiagnoseUninitializedFields(*this, Constructor); +    return false;  } @@ -4234,7 +4480,7 @@ void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) {        if (!SO->second.front().Method->isPure())          continue; -      if (!SeenPureMethods.insert(SO->second.front().Method)) +      if (!SeenPureMethods.insert(SO->second.front().Method).second)          continue;        Diag(SO->second.front().Method->getLocation(),  @@ -4415,10 +4661,53 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info,  /// \brief Check class-level dllimport/dllexport attribute.  static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {    Attr *ClassAttr = getDLLAttr(Class); + +  // MSVC inherits DLL attributes to partial class template specializations. +  if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) { +    if (auto *Spec = dyn_cast<ClassTemplatePartialSpecializationDecl>(Class)) { +      if (Attr *TemplateAttr = +              getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) { +        auto *A = cast<InheritableAttr>(TemplateAttr->clone(S.getASTContext())); +        A->setInherited(true); +        ClassAttr = A; +      } +    } +  } +    if (!ClassAttr)      return; -  bool ClassExported = ClassAttr->getKind() == attr::DLLExport; +  if (!Class->isExternallyVisible()) { +    S.Diag(Class->getLocation(), diag::err_attribute_dll_not_extern) +        << Class << ClassAttr; +    return; +  } + +  if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && +      !ClassAttr->isInherited()) { +    // Diagnose dll attributes on members of class with dll attribute. +    for (Decl *Member : Class->decls()) { +      if (!isa<VarDecl>(Member) && !isa<CXXMethodDecl>(Member)) +        continue; +      InheritableAttr *MemberAttr = getDLLAttr(Member); +      if (!MemberAttr || MemberAttr->isInherited() || Member->isInvalidDecl()) +        continue; + +      S.Diag(MemberAttr->getLocation(), +             diag::err_attribute_dll_member_of_dll_class) +          << MemberAttr << ClassAttr; +      S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute); +      Member->setInvalidDecl(); +    } +  } + +  if (Class->getDescribedClassTemplate()) +    // Don't inherit dll attribute until the template is instantiated. +    return; + +  // The class is either imported or exported. +  const bool ClassExported = ClassAttr->getKind() == attr::DLLExport; +  const bool ClassImported = !ClassExported;    // Force declaration of implicit members so they can inherit the attribute.    S.ForceDeclarationOfImplicitMembers(Class); @@ -4426,6 +4715,9 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {    // FIXME: MSVC's docs say all bases must be exportable, but this doesn't    // seem to be true in practice? +  TemplateSpecializationKind TSK = +    Class->getTemplateSpecializationKind(); +    for (Decl *Member : Class->decls()) {      VarDecl *VD = dyn_cast<VarDecl>(Member);      CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member); @@ -4434,50 +4726,57 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {      if (!VD && !MD)        continue; -    // Don't process deleted methods. -    if (MD && MD->isDeleted()) -      continue; +    if (MD) { +      // Don't process deleted methods. +      if (MD->isDeleted()) +        continue; -    if (MD && MD->isMoveAssignmentOperator() && !ClassExported && -        MD->isInlined()) { -      // Current MSVC versions don't export the move assignment operators, so -      // don't attempt to import them if we have a definition. -      continue; -    } +      if (MD->isMoveAssignmentOperator() && ClassImported && MD->isInlined()) { +        // Current MSVC versions don't export the move assignment operators, so +        // don't attempt to import them if we have a definition. +        continue; +      } -    if (InheritableAttr *MemberAttr = getDLLAttr(Member)) { -      if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && -          !MemberAttr->isInherited() && !ClassAttr->isInherited()) { -        S.Diag(MemberAttr->getLocation(), -               diag::err_attribute_dll_member_of_dll_class) -            << MemberAttr << ClassAttr; -        S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute); -        Member->setInvalidDecl(); +      if (MD->isInlined() && ClassImported && +          !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { +        // MinGW does not import inline functions.          continue;        } -    } else { +    } + +    if (!getDLLAttr(Member)) {        auto *NewAttr =            cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));        NewAttr->setInherited(true);        Member->addAttr(NewAttr);      } -    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) { -      if (ClassExported) { -        if (MD->isUserProvided()) { -          // Instantiate non-default methods. -          S.MarkFunctionReferenced(Class->getLocation(), MD); -        } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() || -                   MD->isCopyAssignmentOperator() || -                   MD->isMoveAssignmentOperator()) { -          // Instantiate non-trivial or explicitly defaulted methods, and the -          // copy assignment / move assignment operators. -          S.MarkFunctionReferenced(Class->getLocation(), MD); -          // Resolve its exception specification; CodeGen needs it. -          auto *FPT = MD->getType()->getAs<FunctionProtoType>(); -          S.ResolveExceptionSpec(Class->getLocation(), FPT); -          S.ActOnFinishInlineMethodDef(MD); -        } +    if (MD && ClassExported) { +      if (MD->isUserProvided()) { +        // Instantiate non-default class member functions ... + +        // .. except for certain kinds of template specializations. +        if (TSK == TSK_ExplicitInstantiationDeclaration) +          continue; +        if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited()) +          continue; + +        S.MarkFunctionReferenced(Class->getLocation(), MD); + +        // The function will be passed to the consumer when its definition is +        // encountered. +      } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() || +                 MD->isCopyAssignmentOperator() || +                 MD->isMoveAssignmentOperator()) { +        // Synthesize and instantiate non-trivial implicit methods, explicitly +        // defaulted methods, and the copy and move assignment operators. The +        // latter are exported even if they are trivial, because the address of +        // an operator can be taken and should compare equal accross libraries. +        S.MarkFunctionReferenced(Class->getLocation(), MD); + +        // There is no later point when we will see the definition of this +        // function, so pass it to the consumer now. +        S.Consumer.HandleTopLevelDecl(DeclGroupRef(MD));        }      }    } @@ -4563,13 +4862,18 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {      }    } +  bool HasMethodWithOverrideControl = false, +       HasOverridingMethodWithoutOverrideControl = false;    if (!Record->isDependentType()) {      for (auto *M : Record->methods()) {        // See if a method overloads virtual methods in a base        // class without overriding any.        if (!M->isStatic())          DiagnoseHiddenVirtualMethods(M); - +      if (M->hasAttr<OverrideAttr>()) +        HasMethodWithOverrideControl = true; +      else if (M->size_overridden_methods() > 0) +        HasOverridingMethodWithoutOverrideControl = true;        // Check whether the explicitly-defaulted special members are valid.        if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())          CheckExplicitlyDefaultedSpecialMember(M); @@ -4588,41 +4892,12 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {      }    } -  // C++11 [dcl.constexpr]p8: A constexpr specifier for a non-static member -  // function that is not a constructor declares that member function to be -  // const. [...] The class of which that function is a member shall be -  // a literal type. -  // -  // If the class has virtual bases, any constexpr members will already have -  // been diagnosed by the checks performed on the member declaration, so -  // suppress this (less useful) diagnostic. -  // -  // We delay this until we know whether an explicitly-defaulted (or deleted) -  // destructor for the class is trivial. -  if (LangOpts.CPlusPlus11 && !Record->isDependentType() && -      !Record->isLiteral() && !Record->getNumVBases()) { -    for (const auto *M : Record->methods()) { -      if (M->isConstexpr() && M->isInstance() && !isa<CXXConstructorDecl>(M)) { -        switch (Record->getTemplateSpecializationKind()) { -        case TSK_ImplicitInstantiation: -        case TSK_ExplicitInstantiationDeclaration: -        case TSK_ExplicitInstantiationDefinition: -          // If a template instantiates to a non-literal type, but its members -          // instantiate to constexpr functions, the template is technically -          // ill-formed, but we allow it for sanity. -          continue; - -        case TSK_Undeclared: -        case TSK_ExplicitSpecialization: -          RequireLiteralType(M->getLocation(), Context.getRecordType(Record), -                             diag::err_constexpr_method_non_literal); -          break; -        } - -        // Only produce one error per class. -        break; -      } -    } +  if (HasMethodWithOverrideControl && +      HasOverridingMethodWithoutOverrideControl) { +    // At least one method has the 'override' control declared. +    // Diagnose all other overridden methods which do not have 'override' specified on them. +    for (auto *M : Record->methods()) +      DiagnoseAbsenceOfOverrideControl(M);    }    // ms_struct is a request to use the same ABI rules as MSVC.  Check @@ -4723,7 +4998,7 @@ static bool defaultedSpecialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,    case Sema::CXXCopyAssignment:    case Sema::CXXMoveAssignment: -    if (!S.getLangOpts().CPlusPlus1y) +    if (!S.getLangOpts().CPlusPlus14)        return false;      // In C++1y, we need to perform overload resolution.      Ctor = false; @@ -4818,8 +5093,8 @@ static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S,    FunctionProtoType::ExtProtoInfo EPI;    // Build an exception specification pointing back at this member. -  EPI.ExceptionSpecType = EST_Unevaluated; -  EPI.ExceptionSpecDecl = MD; +  EPI.ExceptionSpec.Type = EST_Unevaluated; +  EPI.ExceptionSpec.SourceDecl = MD;    // Set the calling convention to the default for C++ instance methods.    EPI.ExtInfo = EPI.ExtInfo.withCallingConv( @@ -4834,14 +5109,10 @@ void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD)      return;    // Evaluate the exception specification. -  ImplicitExceptionSpecification ExceptSpec = -      computeImplicitExceptionSpec(*this, Loc, MD); - -  FunctionProtoType::ExtProtoInfo EPI; -  ExceptSpec.getEPI(EPI); +  auto ESI = computeImplicitExceptionSpec(*this, Loc, MD).getExceptionSpec();    // Update the type of the special member to use it. -  UpdateExceptionSpec(MD, EPI); +  UpdateExceptionSpec(MD, ESI);    // A user-provided destructor can be defined outside the class. When that    // happens, be sure to update the exception specification on both @@ -4849,7 +5120,7 @@ void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD)    const FunctionProtoType *CanonicalFPT =      MD->getCanonicalDecl()->getType()->castAs<FunctionProtoType>();    if (CanonicalFPT->getExceptionSpecType() == EST_Unevaluated) -    UpdateExceptionSpec(MD->getCanonicalDecl(), EPI); +    UpdateExceptionSpec(MD->getCanonicalDecl(), ESI);  }  void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { @@ -4911,7 +5182,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {      // A defaulted special member cannot have cv-qualifiers.      if (Type->getTypeQuals()) {        Diag(MD->getLocation(), diag::err_defaulted_special_member_quals) -        << (CSM == CXXMoveAssignment) << getLangOpts().CPlusPlus1y; +        << (CSM == CXXMoveAssignment) << getLangOpts().CPlusPlus14;        HadError = true;      }    } @@ -4960,7 +5231,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {    // destructors in C++1y), this is checked elsewhere.    bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, RD, CSM,                                                       HasConstParam); -  if ((getLangOpts().CPlusPlus1y ? !isa<CXXDestructorDecl>(MD) +  if ((getLangOpts().CPlusPlus14 ? !isa<CXXDestructorDecl>(MD)                                   : isa<CXXConstructorDecl>(MD)) &&        MD->isConstexpr() && !Constexpr &&        MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { @@ -4995,10 +5266,10 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {      //  -- it is implicitly considered to have the same exception-specification      //     as if it had been implicitly declared,      FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo(); -    EPI.ExceptionSpecType = EST_Unevaluated; -    EPI.ExceptionSpecDecl = MD; +    EPI.ExceptionSpec.Type = EST_Unevaluated; +    EPI.ExceptionSpec.SourceDecl = MD;      MD->setType(Context.getFunctionType(ReturnType, -                                        ArrayRef<QualType>(&ArgType, +                                        llvm::makeArrayRef(&ArgType,                                                             ExpectedParams),                                          EPI));    } @@ -5026,11 +5297,18 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {  /// C++11 [dcl.fct.def.default]p2.  void Sema::CheckExplicitlyDefaultedMemberExceptionSpec(      CXXMethodDecl *MD, const FunctionProtoType *SpecifiedType) { +  // If the exception specification was explicitly specified but hadn't been +  // parsed when the method was defaulted, grab it now. +  if (SpecifiedType->getExceptionSpecType() == EST_Unparsed) +    SpecifiedType = +        MD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>(); +    // Compute the implicit exception specification.    CallingConv CC = Context.getDefaultCallingConvention(/*IsVariadic=*/false,                                                         /*IsCXXMethod=*/true);    FunctionProtoType::ExtProtoInfo EPI(CC); -  computeImplicitExceptionSpec(*this, MD->getLocation(), MD).getEPI(EPI); +  EPI.ExceptionSpec = computeImplicitExceptionSpec(*this, MD->getLocation(), MD) +                          .getExceptionSpec();    const FunctionProtoType *ImplicitType = cast<FunctionProtoType>(      Context.getFunctionType(Context.VoidTy, None, EPI)); @@ -5043,27 +5321,21 @@ void Sema::CheckExplicitlyDefaultedMemberExceptionSpec(  }  void Sema::CheckDelayedMemberExceptionSpecs() { -  SmallVector<std::pair<const CXXDestructorDecl *, const CXXDestructorDecl *>, -              2> Checks; -  SmallVector<std::pair<CXXMethodDecl *, const FunctionProtoType *>, 2> Specs; +  decltype(DelayedExceptionSpecChecks) Checks; +  decltype(DelayedDefaultedMemberExceptionSpecs) Specs; -  std::swap(Checks, DelayedDestructorExceptionSpecChecks); +  std::swap(Checks, DelayedExceptionSpecChecks);    std::swap(Specs, DelayedDefaultedMemberExceptionSpecs);    // Perform any deferred checking of exception specifications for virtual    // destructors. -  for (unsigned i = 0, e = Checks.size(); i != e; ++i) { -    const CXXDestructorDecl *Dtor = Checks[i].first; -    assert(!Dtor->getParent()->isDependentType() && -           "Should not ever add destructors of templates into the list."); -    CheckOverridingFunctionExceptionSpec(Dtor, Checks[i].second); -  } +  for (auto &Check : Checks) +    CheckOverridingFunctionExceptionSpec(Check.first, Check.second);    // Check that any explicitly-defaulted methods have exception specifications    // compatible with their implicit exception specifications. -  for (unsigned I = 0, N = Specs.size(); I != N; ++I) -    CheckExplicitlyDefaultedMemberExceptionSpec(Specs[I].first, -                                                Specs[I].second); +  for (auto &Spec : Specs) +    CheckExplicitlyDefaultedMemberExceptionSpec(Spec.first, Spec.second);  }  namespace { @@ -5491,6 +5763,13 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,    if (SMI.shouldDeleteForAllConstMembers())      return true; +  if (getLangOpts().CUDA) { +    // We should delete the special member in CUDA mode if target inference +    // failed. +    return inferCUDATargetForImplicitSpecialMember(RD, CSM, MD, SMI.ConstArg, +                                                   Diagnose); +  } +    return false;  } @@ -5907,7 +6186,7 @@ namespace {  /// \brief Check whether any most overriden method from MD in Methods  static bool CheckMostOverridenMethods(const CXXMethodDecl *MD, -                   const llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) { +                  const llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) {    if (MD->size_overridden_methods() == 0)      return Methods.count(MD->getCanonicalDecl());    for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), @@ -5945,7 +6224,14 @@ static bool FindHiddenVirtualMethod(const CXXBaseSpecifier *Specifier,        if (!MD->isVirtual())          continue;        // If the method we are checking overrides a method from its base -      // don't warn about the other overloaded methods. +      // don't warn about the other overloaded methods. Clang deviates from GCC +      // by only diagnosing overloads of inherited virtual functions that do not +      // override any other virtual functions in the base. GCC's +      // -Woverloaded-virtual diagnoses any derived function hiding a virtual +      // function from a base class. These cases may be better served by a +      // warning (not specific to virtual functions) on call sites when the call +      // would select a different function from the base class, were it visible. +      // See FIXME in test/SemaCXX/warn-overload-virtual.cpp for an example.        if (!Data.S->IsOverload(Data.Method, MD, false))          return true;        // Collect the overload only if its hidden. @@ -5962,7 +6248,7 @@ static bool FindHiddenVirtualMethod(const CXXBaseSpecifier *Specifier,  /// \brief Add the most overriden methods from MD to Methods  static void AddMostOverridenMethods(const CXXMethodDecl *MD, -                         llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) { +                        llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) {    if (MD->size_overridden_methods() == 0)      Methods.insert(MD->getCanonicalDecl());    for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), @@ -6515,6 +6801,22 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,    return Context.getFunctionType(Context.VoidTy, None, EPI);  } +static void extendLeft(SourceRange &R, const SourceRange &Before) { +  if (Before.isInvalid()) +    return; +  R.setBegin(Before.getBegin()); +  if (R.getEnd().isInvalid()) +    R.setEnd(Before.getEnd()); +} + +static void extendRight(SourceRange &R, const SourceRange &After) { +  if (After.isInvalid()) +    return; +  if (R.getBegin().isInvalid()) +    R.setBegin(After.getBegin()); +  R.setEnd(After.getEnd()); +} +  /// CheckConversionDeclarator - Called by ActOnDeclarator to check the  /// well-formednes of the conversion function declarator @p D with  /// type @p R. If there are any errors in the declarator, this routine @@ -6536,7 +6838,9 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,      SC = SC_None;    } -  QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId); +  TypeSourceInfo *ConvTSI = nullptr; +  QualType ConvType = +      GetTypeFromParser(D.getName().ConversionFunctionId, &ConvTSI);    if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {      // Conversion functions don't have return types, but the parser will @@ -6570,9 +6874,75 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,    // Diagnose "&operator bool()" and other such nonsense.  This    // is actually a gcc extension which we don't support.    if (Proto->getReturnType() != ConvType) { -    Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl) -        << Proto->getReturnType(); -    D.setInvalidType(); +    bool NeedsTypedef = false; +    SourceRange Before, After; + +    // Walk the chunks and extract information on them for our diagnostic. +    bool PastFunctionChunk = false; +    for (auto &Chunk : D.type_objects()) { +      switch (Chunk.Kind) { +      case DeclaratorChunk::Function: +        if (!PastFunctionChunk) { +          if (Chunk.Fun.HasTrailingReturnType) { +            TypeSourceInfo *TRT = nullptr; +            GetTypeFromParser(Chunk.Fun.getTrailingReturnType(), &TRT); +            if (TRT) extendRight(After, TRT->getTypeLoc().getSourceRange()); +          } +          PastFunctionChunk = true; +          break; +        } +        // Fall through. +      case DeclaratorChunk::Array: +        NeedsTypedef = true; +        extendRight(After, Chunk.getSourceRange()); +        break; + +      case DeclaratorChunk::Pointer: +      case DeclaratorChunk::BlockPointer: +      case DeclaratorChunk::Reference: +      case DeclaratorChunk::MemberPointer: +        extendLeft(Before, Chunk.getSourceRange()); +        break; + +      case DeclaratorChunk::Paren: +        extendLeft(Before, Chunk.Loc); +        extendRight(After, Chunk.EndLoc); +        break; +      } +    } + +    SourceLocation Loc = Before.isValid() ? Before.getBegin() : +                         After.isValid()  ? After.getBegin() : +                                            D.getIdentifierLoc(); +    auto &&DB = Diag(Loc, diag::err_conv_function_with_complex_decl); +    DB << Before << After; + +    if (!NeedsTypedef) { +      DB << /*don't need a typedef*/0; + +      // If we can provide a correct fix-it hint, do so. +      if (After.isInvalid() && ConvTSI) { +        SourceLocation InsertLoc = +            PP.getLocForEndOfToken(ConvTSI->getTypeLoc().getLocEnd()); +        DB << FixItHint::CreateInsertion(InsertLoc, " ") +           << FixItHint::CreateInsertionFromRange( +                  InsertLoc, CharSourceRange::getTokenRange(Before)) +           << FixItHint::CreateRemoval(Before); +      } +    } else if (!Proto->getReturnType()->isDependentType()) { +      DB << /*typedef*/1 << Proto->getReturnType(); +    } else if (getLangOpts().CPlusPlus11) { +      DB << /*alias template*/2 << Proto->getReturnType(); +    } else { +      DB << /*might not be fixable*/3; +    } + +    // Recover by incorporating the other type chunks into the result type. +    // Note, this does *not* change the name of the function. This is compatible +    // with the GCC extension: +    //   struct S { &operator int(); } s; +    //   int &r = s.operator int(); // ok in GCC +    //   S::operator int&() {} // error in GCC, function name is 'operator int'.      ConvType = Proto->getReturnType();    } @@ -6893,7 +7263,7 @@ NamespaceDecl *Sema::getOrCreateStdNamespace() {                                           /*PrevDecl=*/nullptr);      getStdNamespace()->setImplicit(true);    } -   +    return getStdNamespace();  } @@ -7054,12 +7424,11 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc,                                         CXXScopeSpec &SS,                                         SourceLocation IdentLoc,                                         IdentifierInfo *Ident) { -  NamespaceValidatorCCC Validator;    R.clear(); -  if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(), -                                               R.getLookupKind(), Sc, &SS, -                                               Validator, -                                               Sema::CTK_ErrorRecovery)) { +  if (TypoCorrection Corrected = +          S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, +                        llvm::make_unique<NamespaceValidatorCCC>(), +                        Sema::CTK_ErrorRecovery)) {      if (DeclContext *DC = S.computeDeclContext(SS, false)) {        std::string CorrectedStr(Corrected.getAsString(S.getLangOpts()));        bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && @@ -7124,6 +7493,10 @@ Decl *Sema::ActOnUsingDirective(Scope *S,      NamedDecl *Named = R.getFoundDecl();      assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named))          && "expected namespace decl"); + +    // The use of a nested name specifier may trigger deprecation warnings. +    DiagnoseUseOfDecl(Named, IdentLoc); +      // C++ [namespace.udir]p1:      //   A using-directive specifies that the names in the nominated      //   namespace can be used in the scope in which the @@ -7685,11 +8058,12 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,    // Try to correct typos if possible.    if (R.empty()) { -    UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), -                          dyn_cast<CXXRecordDecl>(CurContext)); -    if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), -                                               R.getLookupKind(), S, &SS, CCC, -                                               CTK_ErrorRecovery)){ +    if (TypoCorrection Corrected = CorrectTypo( +            R.getLookupNameInfo(), R.getLookupKind(), S, &SS, +            llvm::make_unique<UsingValidatorCCC>( +                HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), +                dyn_cast<CXXRecordDecl>(CurContext)), +            CTK_ErrorRecovery)) {        // We reject any correction for which ND would be NULL.        NamedDecl *ND = Corrected.getCorrectionDecl(); @@ -7874,7 +8248,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,      // If we weren't able to compute a valid scope, it must be a      // dependent class scope.      if (!NamedContext || NamedContext->isRecord()) { -      auto *RD = dyn_cast<CXXRecordDecl>(NamedContext); +      auto *RD = dyn_cast_or_null<CXXRecordDecl>(NamedContext);        if (RD && RequireCompleteDeclContext(const_cast<CXXScopeSpec&>(SS), RD))          RD = nullptr; @@ -8164,6 +8538,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S,        TypeAliasTemplateDecl::Create(Context, CurContext, UsingLoc,                                      Name.Identifier, TemplateParams,                                      NewTD); +    NewTD->setDescribedAliasTemplate(NewDecl);      NewDecl->setAccess(AS); @@ -8185,57 +8560,65 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S,    return NewND;  } -Decl *Sema::ActOnNamespaceAliasDef(Scope *S, -                                             SourceLocation NamespaceLoc, -                                             SourceLocation AliasLoc, -                                             IdentifierInfo *Alias, -                                             CXXScopeSpec &SS, -                                             SourceLocation IdentLoc, -                                             IdentifierInfo *Ident) { +Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, +                                   SourceLocation AliasLoc, +                                   IdentifierInfo *Alias, CXXScopeSpec &SS, +                                   SourceLocation IdentLoc, +                                   IdentifierInfo *Ident) {    // Lookup the namespace name.    LookupResult R(*this, Ident, IdentLoc, LookupNamespaceName);    LookupParsedName(R, S, &SS); +  if (R.isAmbiguous()) +    return nullptr; + +  if (R.empty()) { +    if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { +      Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); +      return nullptr; +    } +  } +  assert(!R.isAmbiguous() && !R.empty()); +    // Check if we have a previous declaration with the same name. -  NamedDecl *PrevDecl -    = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName,  -                       ForRedeclaration); +  NamedDecl *PrevDecl = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, +                                         ForRedeclaration);    if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S))      PrevDecl = nullptr; +  NamedDecl *ND = R.getFoundDecl(); +    if (PrevDecl) {      if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {        // We already have an alias with the same name that points to the same -      // namespace, so don't create a new one. -      // FIXME: At some point, we'll want to create the (redundant) -      // declaration to maintain better source information. -      if (!R.isAmbiguous() && !R.empty() && -          AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl()))) +      // namespace; check that it matches. +      if (!AD->getNamespace()->Equals(getNamespaceDecl(ND))) { +        Diag(AliasLoc, diag::err_redefinition_different_namespace_alias) +          << Alias; +        Diag(PrevDecl->getLocation(), diag::note_previous_namespace_alias) +          << AD->getNamespace();          return nullptr; -    } - -    unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition : -      diag::err_redefinition_different_kind; -    Diag(AliasLoc, DiagID) << Alias; -    Diag(PrevDecl->getLocation(), diag::note_previous_definition); -    return nullptr; -  } - -  if (R.isAmbiguous()) -    return nullptr; - -  if (R.empty()) { -    if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { -      Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); +      } +    } else { +      unsigned DiagID = isa<NamespaceDecl>(PrevDecl) +                            ? diag::err_redefinition +                            : diag::err_redefinition_different_kind; +      Diag(AliasLoc, DiagID) << Alias; +      Diag(PrevDecl->getLocation(), diag::note_previous_definition);        return nullptr;      }    } +  // The use of a nested name specifier may trigger deprecation warnings. +  DiagnoseUseOfDecl(ND, IdentLoc); +    NamespaceAliasDecl *AliasDecl =      NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc,                                 Alias, SS.getWithLocInContext(Context), -                               IdentLoc, R.getFoundDecl()); +                               IdentLoc, ND); +  if (PrevDecl) +    AliasDecl->setPreviousDecl(cast<NamespaceAliasDecl>(PrevDecl));    PushOnScopeChains(AliasDecl, S);    return AliasDecl; @@ -8285,22 +8668,6 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,      if (F->hasInClassInitializer()) {        if (Expr *E = F->getInClassInitializer())          ExceptSpec.CalledExpr(E); -      else if (!F->isInvalidDecl()) -        // DR1351: -        //   If the brace-or-equal-initializer of a non-static data member -        //   invokes a defaulted default constructor of its class or of an -        //   enclosing class in a potentially evaluated subexpression, the -        //   program is ill-formed. -        // -        // This resolution is unworkable: the exception specification of the -        // default constructor can be needed in an unevaluated context, in -        // particular, in the operand of a noexcept-expression, and we can be -        // unable to compute an exception specification for an enclosed class. -        // -        // We do not allow an in-class initializer to require the evaluation -        // of the exception specification for any in-class initializer whose -        // definition is not lexically complete. -        Diag(Loc, diag::err_in_class_initializer_references_def_ctor) << MD;      } else if (const RecordType *RecordTy                = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {        CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); @@ -8368,9 +8735,6 @@ Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) {      if (F->hasInClassInitializer()) {        if (Expr *E = F->getInClassInitializer())          ExceptSpec.CalledExpr(E); -      else if (!F->isInvalidDecl()) -        Diag(CD->getLocation(), -             diag::err_in_class_initializer_references_def_ctor) << CD;      } else if (const RecordType *RecordTy                = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {        CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); @@ -8392,7 +8756,7 @@ struct DeclaringSpecialMember {    DeclaringSpecialMember(Sema &S, CXXRecordDecl *RD, Sema::CXXSpecialMember CSM)      : S(S), D(RD, CSM) { -    WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D); +    WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D).second;      if (WasAlreadyBeingDeclared)        // This almost never happens, but if it does, ensure that our cache        // doesn't contain a stale result. @@ -8421,7 +8785,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(    //   user-declared constructor for class X, a default constructor is    //   implicitly declared. An implicitly-declared default constructor    //   is an inline public member of its class. -  assert(ClassDecl->needsImplicitDefaultConstructor() &&  +  assert(ClassDecl->needsImplicitDefaultConstructor() &&           "Should not build implicit default constructor!");    DeclaringSpecialMember DSM(*this, ClassDecl, CXXDefaultConstructor); @@ -8445,7 +8809,13 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(        /*isImplicitlyDeclared=*/true, Constexpr);    DefaultCon->setAccess(AS_public);    DefaultCon->setDefaulted(); -  DefaultCon->setImplicit(); + +  if (getLangOpts().CUDA) { +    inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXDefaultConstructor, +                                            DefaultCon, +                                            /* ConstRHS */ false, +                                            /* Diagnose */ false); +  }    // Build an exception specification pointing back at this constructor.    FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, DefaultCon); @@ -8488,6 +8858,11 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,      return;    } +  // The exception specification is needed because we are defining the +  // function. +  ResolveExceptionSpec(CurrentLocation, +                       Constructor->getType()->castAs<FunctionProtoType>()); +    SourceLocation Loc = Constructor->getLocEnd().isValid()                             ? Constructor->getLocEnd()                             : Constructor->getLocation(); @@ -8597,7 +8972,7 @@ private:    void inherit(const CXXConstructorDecl *Ctor) {      const FunctionProtoType *CtorType =          Ctor->getType()->castAs<FunctionProtoType>(); -    ArrayRef<QualType> ArgTypes(CtorType->getParamTypes()); +    ArrayRef<QualType> ArgTypes = CtorType->getParamTypes();      FunctionProtoType::ExtProtoInfo EPI = CtorType->getExtProtoInfo();      SourceLocation UsingLoc = getUsingLoc(Ctor->getParent()); @@ -8737,8 +9112,8 @@ private:      // Build an unevaluated exception specification for this constructor.      const FunctionProtoType *FPT = DerivedType->castAs<FunctionProtoType>();      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); -    EPI.ExceptionSpecType = EST_Unevaluated; -    EPI.ExceptionSpecDecl = DerivedCtor; +    EPI.ExceptionSpec.Type = EST_Unevaluated; +    EPI.ExceptionSpec.SourceDecl = DerivedCtor;      DerivedCtor->setType(Context.getFunctionType(FPT->getReturnType(),                                                   FPT->getParamTypes(), EPI)); @@ -8900,7 +9275,13 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {                                    /*isImplicitlyDeclared=*/true);    Destructor->setAccess(AS_public);    Destructor->setDefaulted(); -  Destructor->setImplicit(); + +  if (getLangOpts().CUDA) { +    inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXDestructor, +                                            Destructor, +                                            /* ConstRHS */ false, +                                            /* Diagnose */ false); +  }    // Build an exception specification pointing back at this destructor.    FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, Destructor); @@ -8952,6 +9333,11 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,      return;    } +  // The exception specification is needed because we are defining the +  // function. +  ResolveExceptionSpec(CurrentLocation, +                       Destructor->getType()->castAs<FunctionProtoType>()); +    SourceLocation Loc = Destructor->getLocEnd().isValid()                             ? Destructor->getLocEnd()                             : Destructor->getLocation(); @@ -8971,7 +9357,7 @@ void Sema::ActOnFinishCXXMemberDecls() {    if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(CurContext)) {      if (Record->isInvalidDecl()) {        DelayedDefaultedMemberExceptionSpecs.clear(); -      DelayedDestructorExceptionSpecChecks.clear(); +      DelayedExceptionSpecChecks.clear();        return;      }    } @@ -8995,8 +9381,8 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,    // the only thing of interest in the destructor type is its extended info.    // The return and arguments are fixed.    FunctionProtoType::ExtProtoInfo EPI = DtorType->getExtProtoInfo(); -  EPI.ExceptionSpecType = EST_Unevaluated; -  EPI.ExceptionSpecDecl = Destructor; +  EPI.ExceptionSpec.Type = EST_Unevaluated; +  EPI.ExceptionSpec.SourceDecl = Destructor;    Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI));    // FIXME: If the destructor has a body that could throw, and the newly created @@ -9032,7 +9418,7 @@ class RefBuilder: public ExprBuilder {    QualType VarType;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).get());    } @@ -9042,7 +9428,7 @@ public:  class ThisBuilder: public ExprBuilder {  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(S.ActOnCXXThis(Loc).getAs<Expr>());    }  }; @@ -9054,7 +9440,7 @@ class CastBuilder: public ExprBuilder {    const CXXCastPath &Path;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(S.ImpCastExprToType(Builder.build(S, Loc), Type,                                               CK_UncheckedDerivedToBase, Kind,                                               &Path).get()); @@ -9069,7 +9455,7 @@ class DerefBuilder: public ExprBuilder {    const ExprBuilder &Builder;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(          S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).get());    } @@ -9085,7 +9471,7 @@ class MemberBuilder: public ExprBuilder {    LookupResult &MemberLookup;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(S.BuildMemberReferenceExpr(          Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(),          nullptr, MemberLookup, nullptr).get()); @@ -9101,7 +9487,7 @@ class MoveCastBuilder: public ExprBuilder {    const ExprBuilder &Builder;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(CastForMoving(S, Builder.build(S, Loc)));    } @@ -9112,7 +9498,7 @@ class LvalueConvBuilder: public ExprBuilder {    const ExprBuilder &Builder;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(          S.DefaultLvalueConversion(Builder.build(S, Loc)).get());    } @@ -9125,7 +9511,7 @@ class SubscriptBuilder: public ExprBuilder {    const ExprBuilder &Index;  public: -  virtual Expr *build(Sema &S, SourceLocation Loc) const override { +  Expr *build(Sema &S, SourceLocation Loc) const override {      return assertNotNull(S.CreateBuiltinArraySubscriptExpr(          Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).get());    } @@ -9521,6 +9907,13 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {    CopyAssignment->setDefaulted();    CopyAssignment->setImplicit(); +  if (getLangOpts().CUDA) { +    inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXCopyAssignment, +                                            CopyAssignment, +                                            /* ConstRHS */ Const, +                                            /* Diagnose */ false); +  } +    // Build an exception specification pointing back at this member.    FunctionProtoType::ExtProtoInfo EPI =        getImplicitMethodEPI(*this, CopyAssignment); @@ -9795,6 +10188,11 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,      }    } +  // The exception specification is needed because we are defining the +  // function. +  ResolveExceptionSpec(CurrentLocation, +                       CopyAssignOperator->getType()->castAs<FunctionProtoType>()); +    if (Invalid) {      CopyAssignOperator->setInvalidDecl();      return; @@ -9898,6 +10296,13 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {    MoveAssignment->setDefaulted();    MoveAssignment->setImplicit(); +  if (getLangOpts().CUDA) { +    inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXMoveAssignment, +                                            MoveAssignment, +                                            /* ConstRHS */ false, +                                            /* Diagnose */ false); +  } +    // Build an exception specification pointing back at this member.    FunctionProtoType::ExtProtoInfo EPI =        getImplicitMethodEPI(*this, MoveAssignment); @@ -10217,6 +10622,11 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,      }    } +  // The exception specification is needed because we are defining the +  // function. +  ResolveExceptionSpec(CurrentLocation, +                       MoveAssignOperator->getType()->castAs<FunctionProtoType>()); +    if (Invalid) {      MoveAssignOperator->setInvalidDecl();      return; @@ -10319,6 +10729,13 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(    CopyConstructor->setAccess(AS_public);    CopyConstructor->setDefaulted(); +  if (getLangOpts().CUDA) { +    inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXCopyConstructor, +                                            CopyConstructor, +                                            /* ConstRHS */ Const, +                                            /* Diagnose */ false); +  } +    // Build an exception specification pointing back at this member.    FunctionProtoType::ExtProtoInfo EPI =        getImplicitMethodEPI(*this, CopyConstructor); @@ -10386,6 +10803,11 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,          ActOnCompoundStmt(Loc, Loc, None, /*isStmtExpr=*/false).getAs<Stmt>());    } +  // The exception specification is needed because we are defining the +  // function. +  ResolveExceptionSpec(CurrentLocation, +                       CopyConstructor->getType()->castAs<FunctionProtoType>()); +    CopyConstructor->markUsed(Context);    MarkVTableUsed(CurrentLocation, ClassDecl); @@ -10484,6 +10906,13 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(    MoveConstructor->setAccess(AS_public);    MoveConstructor->setDefaulted(); +  if (getLangOpts().CUDA) { +    inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXMoveConstructor, +                                            MoveConstructor, +                                            /* ConstRHS */ false, +                                            /* Diagnose */ false); +  } +    // Build an exception specification pointing back at this member.    FunctionProtoType::ExtProtoInfo EPI =        getImplicitMethodEPI(*this, MoveConstructor); @@ -10546,6 +10975,11 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation,          Loc, Loc, None, /*isStmtExpr=*/ false).getAs<Stmt>());    } +  // The exception specification is needed because we are defining the +  // function. +  ResolveExceptionSpec(CurrentLocation, +                       MoveConstructor->getType()->castAs<FunctionProtoType>()); +    MoveConstructor->markUsed(Context);    MarkVTableUsed(CurrentLocation, ClassDecl); @@ -10765,6 +11199,56 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,        ParenRange);  } +ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { +  assert(Field->hasInClassInitializer()); + +  // If we already have the in-class initializer nothing needs to be done. +  if (Field->getInClassInitializer()) +    return CXXDefaultInitExpr::Create(Context, Loc, Field); + +  // Maybe we haven't instantiated the in-class initializer. Go check the +  // pattern FieldDecl to see if it has one. +  CXXRecordDecl *ParentRD = cast<CXXRecordDecl>(Field->getParent()); + +  if (isTemplateInstantiation(ParentRD->getTemplateSpecializationKind())) { +    CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern(); +    DeclContext::lookup_result Lookup = +        ClassPattern->lookup(Field->getDeclName()); +    assert(Lookup.size() == 1); +    FieldDecl *Pattern = cast<FieldDecl>(Lookup[0]); +    if (InstantiateInClassInitializer(Loc, Field, Pattern, +                                      getTemplateInstantiationArgs(Field))) +      return ExprError(); +    return CXXDefaultInitExpr::Create(Context, Loc, Field); +  } + +  // DR1351: +  //   If the brace-or-equal-initializer of a non-static data member +  //   invokes a defaulted default constructor of its class or of an +  //   enclosing class in a potentially evaluated subexpression, the +  //   program is ill-formed. +  // +  // This resolution is unworkable: the exception specification of the +  // default constructor can be needed in an unevaluated context, in +  // particular, in the operand of a noexcept-expression, and we can be +  // unable to compute an exception specification for an enclosed class. +  // +  // Any attempt to resolve the exception specification of a defaulted default +  // constructor before the initializer is lexically complete will ultimately +  // come here at which point we can diagnose it. +  RecordDecl *OutermostClass = ParentRD->getOuterLexicalRecordContext(); +  if (OutermostClass == ParentRD) { +    Diag(Field->getLocEnd(), diag::err_in_class_initializer_not_yet_parsed) +        << ParentRD << Field; +  } else { +    Diag(Field->getLocEnd(), +         diag::err_in_class_initializer_not_yet_parsed_outer_class) +        << ParentRD << OutermostClass << Field; +  } + +  return ExprError(); +} +  void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {    if (VD->isInvalidDecl()) return; @@ -10834,8 +11318,7 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,    DiagnoseSentinelCalls(Constructor, Loc, AllArgs);    CheckConstructorCall(Constructor, -                       llvm::makeArrayRef<const Expr *>(AllArgs.data(), -                                                        AllArgs.size()), +                       llvm::makeArrayRef(AllArgs.data(), AllArgs.size()),                         Proto, Loc);    return Invalid; @@ -12118,8 +12601,12 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,      }      // Mark templated-scope function declarations as unsupported. -    if (FD->getNumTemplateParameterLists()) +    if (FD->getNumTemplateParameterLists() && SS.isValid()) { +      Diag(FD->getLocation(), diag::warn_template_qualified_friend_unsupported) +        << SS.getScopeRep() << SS.getRange() +        << cast<CXXRecordDecl>(CurContext);        FrD->setUnsupportedFriend(true); +    }    }    return ND; @@ -12220,11 +12707,6 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {      CheckExplicitlyDefaultedSpecialMember(MD); -    // The exception specification is needed because we are defining the -    // function. -    ResolveExceptionSpec(DefaultLoc, -                         MD->getType()->castAs<FunctionProtoType>()); -      if (MD->isInvalidDecl())        return; @@ -12538,7 +13020,7 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,      Pos = VTablesUsed.insert(std::make_pair(Class, DefinitionRequired));    if (!Pos.second) {      // If we already had an entry, check to see if we are promoting this vtable -    // to required a definition. If so, we need to reappend to the VTableUses +    // to require a definition. If so, we need to reappend to the VTableUses      // list, since we may have already processed the first entry.      if (DefinitionRequired && !Pos.first->second) {        Pos.first->second = true; @@ -12739,10 +13221,10 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {        AllToInit.push_back(Member);        // Be sure that the destructor is accessible and is marked as referenced. -      if (const RecordType *RecordTy -                  = Context.getBaseElementType(Field->getType()) -                                                        ->getAs<RecordType>()) { -                    CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); +      if (const RecordType *RecordTy = +              Context.getBaseElementType(Field->getType()) +                  ->getAs<RecordType>()) { +        CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());          if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {            MarkFunctionReferenced(Field->getLocation(), Destructor);            CheckDestructorAccess(Field->getLocation(), Destructor, @@ -12780,7 +13262,7 @@ void DelegatingCycleHelper(CXXConstructorDecl* Ctor,                       // Avoid dereferencing a null pointer here.                       *TCanonical = Target? Target->getCanonicalDecl() : nullptr; -  if (!Current.insert(Canonical)) +  if (!Current.insert(Canonical).second)      return;    // We know that beyond here, we aren't chaining into a cycle. @@ -12898,6 +13380,7 @@ bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) {    FindCXXThisExpr Finder(*this);    switch (Proto->getExceptionSpecType()) { +  case EST_Unparsed:    case EST_Uninstantiated:    case EST_Unevaluated:    case EST_BasicNoexcept: @@ -12934,27 +13417,27 @@ bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) {      else if (const auto *G = dyn_cast<PtGuardedByAttr>(A))        Arg = G->getArg();      else if (const auto *AA = dyn_cast<AcquiredAfterAttr>(A)) -      Args = ArrayRef<Expr *>(AA->args_begin(), AA->args_size()); +      Args = llvm::makeArrayRef(AA->args_begin(), AA->args_size());      else if (const auto *AB = dyn_cast<AcquiredBeforeAttr>(A)) -      Args = ArrayRef<Expr *>(AB->args_begin(), AB->args_size()); +      Args = llvm::makeArrayRef(AB->args_begin(), AB->args_size());      else if (const auto *ETLF = dyn_cast<ExclusiveTrylockFunctionAttr>(A)) {        Arg = ETLF->getSuccessValue(); -      Args = ArrayRef<Expr *>(ETLF->args_begin(), ETLF->args_size()); +      Args = llvm::makeArrayRef(ETLF->args_begin(), ETLF->args_size());      } else if (const auto *STLF = dyn_cast<SharedTrylockFunctionAttr>(A)) {        Arg = STLF->getSuccessValue(); -      Args = ArrayRef<Expr *>(STLF->args_begin(), STLF->args_size()); +      Args = llvm::makeArrayRef(STLF->args_begin(), STLF->args_size());      } else if (const auto *LR = dyn_cast<LockReturnedAttr>(A))        Arg = LR->getArg();      else if (const auto *LE = dyn_cast<LocksExcludedAttr>(A)) -      Args = ArrayRef<Expr *>(LE->args_begin(), LE->args_size()); +      Args = llvm::makeArrayRef(LE->args_begin(), LE->args_size());      else if (const auto *RC = dyn_cast<RequiresCapabilityAttr>(A)) -      Args = ArrayRef<Expr *>(RC->args_begin(), RC->args_size()); +      Args = llvm::makeArrayRef(RC->args_begin(), RC->args_size());      else if (const auto *AC = dyn_cast<AcquireCapabilityAttr>(A)) -      Args = ArrayRef<Expr *>(AC->args_begin(), AC->args_size()); +      Args = llvm::makeArrayRef(AC->args_begin(), AC->args_size());      else if (const auto *AC = dyn_cast<TryAcquireCapabilityAttr>(A)) -      Args = ArrayRef<Expr *>(AC->args_begin(), AC->args_size()); +      Args = llvm::makeArrayRef(AC->args_begin(), AC->args_size());      else if (const auto *RC = dyn_cast<ReleaseCapabilityAttr>(A)) -      Args = ArrayRef<Expr *>(RC->args_begin(), RC->args_size()); +      Args = llvm::makeArrayRef(RC->args_begin(), RC->args_size());      if (Arg && !Finder.TraverseStmt(Arg))        return true; @@ -12968,28 +13451,29 @@ bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) {    return false;  } -void -Sema::checkExceptionSpecification(ExceptionSpecificationType EST, -                                  ArrayRef<ParsedType> DynamicExceptions, -                                  ArrayRef<SourceRange> DynamicExceptionRanges, -                                  Expr *NoexceptExpr, -                                  SmallVectorImpl<QualType> &Exceptions, -                                  FunctionProtoType::ExtProtoInfo &EPI) { +void Sema::checkExceptionSpecification( +    bool IsTopLevel, ExceptionSpecificationType EST, +    ArrayRef<ParsedType> DynamicExceptions, +    ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr, +    SmallVectorImpl<QualType> &Exceptions, +    FunctionProtoType::ExceptionSpecInfo &ESI) {    Exceptions.clear(); -  EPI.ExceptionSpecType = EST; +  ESI.Type = EST;    if (EST == EST_Dynamic) {      Exceptions.reserve(DynamicExceptions.size());      for (unsigned ei = 0, ee = DynamicExceptions.size(); ei != ee; ++ei) {        // FIXME: Preserve type source info.        QualType ET = GetTypeFromParser(DynamicExceptions[ei]); -      SmallVector<UnexpandedParameterPack, 2> Unexpanded; -      collectUnexpandedParameterPacks(ET, Unexpanded); -      if (!Unexpanded.empty()) { -        DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(), -                                         UPPC_ExceptionType, -                                         Unexpanded); -        continue; +      if (IsTopLevel) { +        SmallVector<UnexpandedParameterPack, 2> Unexpanded; +        collectUnexpandedParameterPacks(ET, Unexpanded); +        if (!Unexpanded.empty()) { +          DiagnoseUnexpandedParameterPacks( +              DynamicExceptionRanges[ei].getBegin(), UPPC_ExceptionType, +              Unexpanded); +          continue; +        }        }        // Check that the type is valid for an exception spec, and @@ -12997,11 +13481,10 @@ Sema::checkExceptionSpecification(ExceptionSpecificationType EST,        if (!CheckSpecifiedExceptionType(ET, DynamicExceptionRanges[ei]))          Exceptions.push_back(ET);      } -    EPI.NumExceptions = Exceptions.size(); -    EPI.Exceptions = Exceptions.data(); +    ESI.Exceptions = Exceptions;      return;    } -   +    if (EST == EST_ComputedNoexcept) {      // If an error occurred, there's no expression here.      if (NoexceptExpr) { @@ -13009,59 +13492,59 @@ Sema::checkExceptionSpecification(ExceptionSpecificationType EST,                NoexceptExpr->getType()->getCanonicalTypeUnqualified() ==                Context.BoolTy) &&               "Parser should have made sure that the expression is boolean"); -      if (NoexceptExpr && DiagnoseUnexpandedParameterPack(NoexceptExpr)) { -        EPI.ExceptionSpecType = EST_BasicNoexcept; +      if (IsTopLevel && NoexceptExpr && +          DiagnoseUnexpandedParameterPack(NoexceptExpr)) { +        ESI.Type = EST_BasicNoexcept;          return;        } -       +        if (!NoexceptExpr->isValueDependent())          NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, nullptr,                           diag::err_noexcept_needs_constant_expression,                           /*AllowFold*/ false).get(); -      EPI.NoexceptExpr = NoexceptExpr; +      ESI.NoexceptExpr = NoexceptExpr;      }      return;    }  } -/// IdentifyCUDATarget - Determine the CUDA compilation target for this function -Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { -  // Implicitly declared functions (e.g. copy constructors) are -  // __host__ __device__ -  if (D->isImplicit()) -    return CFT_HostDevice; - -  if (D->hasAttr<CUDAGlobalAttr>()) -    return CFT_Global; +void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, +             ExceptionSpecificationType EST, +             SourceRange SpecificationRange, +             ArrayRef<ParsedType> DynamicExceptions, +             ArrayRef<SourceRange> DynamicExceptionRanges, +             Expr *NoexceptExpr) { +  if (!MethodD) +    return; -  if (D->hasAttr<CUDADeviceAttr>()) { -    if (D->hasAttr<CUDAHostAttr>()) -      return CFT_HostDevice; -    return CFT_Device; -  } +  // Dig out the method we're referring to. +  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD)) +    MethodD = FunTmpl->getTemplatedDecl(); -  return CFT_Host; -} +  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(MethodD); +  if (!Method) +    return; -bool Sema::CheckCUDATarget(CUDAFunctionTarget CallerTarget, -                           CUDAFunctionTarget CalleeTarget) { -  // CUDA B.1.1 "The __device__ qualifier declares a function that is... -  // Callable from the device only." -  if (CallerTarget == CFT_Host && CalleeTarget == CFT_Device) -    return true; +  // Check the exception specification. +  llvm::SmallVector<QualType, 4> Exceptions; +  FunctionProtoType::ExceptionSpecInfo ESI; +  checkExceptionSpecification(/*IsTopLevel*/true, EST, DynamicExceptions, +                              DynamicExceptionRanges, NoexceptExpr, Exceptions, +                              ESI); -  // CUDA B.1.2 "The __global__ qualifier declares a function that is... -  // Callable from the host only." -  // CUDA B.1.3 "The __host__ qualifier declares a function that is... -  // Callable from the host only." -  if ((CallerTarget == CFT_Device || CallerTarget == CFT_Global) && -      (CalleeTarget == CFT_Host || CalleeTarget == CFT_Global)) -    return true; +  // Update the exception specification on the function type. +  Context.adjustExceptionSpec(Method, ESI, /*AsWritten*/true); -  if (CallerTarget == CFT_HostDevice && CalleeTarget != CFT_HostDevice) -    return true; +  if (Method->isStatic()) +    checkThisInStaticMemberFunctionExceptionSpec(Method); -  return false; +  if (Method->isVirtual()) { +    // Check overrides, which we previously had to delay. +    for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(), +                                     OEnd = Method->end_overridden_methods(); +         O != OEnd; ++O) +      CheckOverridingFunctionExceptionSpec(Method, *O); +  }  }  /// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class. diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index b5205b3e6238..7e3da941b339 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -118,10 +118,7 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,      // a suitable return type, but the new (overriding) method does not have      // a suitable return type.      QualType ResultType = NewMethod->getReturnType(); -    SourceRange ResultTypeRange; -    if (const TypeSourceInfo *ResultTypeInfo = -            NewMethod->getReturnTypeSourceInfo()) -      ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange(); +    SourceRange ResultTypeRange = NewMethod->getReturnTypeSourceRange();      // Figure out which class this method is part of, if any.      ObjCInterfaceDecl *CurrentClass  @@ -204,15 +201,13 @@ bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {    case OMF_autorelease:    case OMF_retainCount:    case OMF_self: +  case OMF_initialize:    case OMF_performSelector:      return false;    case OMF_dealloc:      if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) { -      SourceRange ResultTypeRange; -      if (const TypeSourceInfo *ResultTypeInfo = -              method->getReturnTypeSourceInfo()) -        ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange(); +      SourceRange ResultTypeRange = method->getReturnTypeSourceRange();        if (ResultTypeRange.isInvalid())          Diag(method->getLocation(), diag::error_dealloc_bad_result_type)              << method->getReturnType() @@ -359,6 +354,7 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {      case OMF_copy:      case OMF_new:      case OMF_self: +    case OMF_initialize:      case OMF_performSelector:        break;      } @@ -520,10 +516,11 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,      if (!PrevDecl) {        // Try to correct for a typo in the superclass name without correcting        // to the class we're defining. -      ObjCInterfaceValidatorCCC Validator(IDecl); -      if (TypoCorrection Corrected = CorrectTypo( -          DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope, -          nullptr, Validator, CTK_ErrorRecovery)) { +      if (TypoCorrection Corrected = +              CorrectTypo(DeclarationNameInfo(SuperName, SuperLoc), +                          LookupOrdinaryName, TUScope, nullptr, +                          llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl), +                          CTK_ErrorRecovery)) {          diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)                                      << SuperName << ClassName);          PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>(); @@ -790,10 +787,10 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,      ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,                                               ProtocolId[i].second);      if (!PDecl) { -      DeclFilterCCC<ObjCProtocolDecl> Validator;        TypoCorrection Corrected = CorrectTypo(            DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second), -          LookupObjCProtocolName, TUScope, nullptr, Validator, +          LookupObjCProtocolName, TUScope, nullptr, +          llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(),            CTK_ErrorRecovery);        if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))          diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) @@ -1031,11 +1028,9 @@ Decl *Sema::ActOnStartClassImplementation(    } else {      // We did not find anything with the name ClassName; try to correct for      // typos in the class name. -    ObjCInterfaceValidatorCCC Validator; -    TypoCorrection Corrected = -            CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), -                        LookupOrdinaryName, TUScope, nullptr, Validator, -                        CTK_NonError); +    TypoCorrection Corrected = CorrectTypo( +        DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope, +        nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError);      if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {        // Suggest the (potentially) correct interface name. Don't provide a        // code-modification hint or use the typo name for recovery, because @@ -1362,9 +1357,9 @@ static bool CheckMethodOverrideReturn(Sema &S,                    ? diag::warn_conflicting_overriding_ret_type_modifiers                    : diag::warn_conflicting_ret_type_modifiers))            << MethodImpl->getDeclName() -          << getTypeRange(MethodImpl->getReturnTypeSourceInfo()); +          << MethodImpl->getReturnTypeSourceRange();        S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration) -          << getTypeRange(MethodDecl->getReturnTypeSourceInfo()); +          << MethodDecl->getReturnTypeSourceRange();      }      else        return false; @@ -1402,11 +1397,11 @@ static bool CheckMethodOverrideReturn(Sema &S,    S.Diag(MethodImpl->getLocation(), DiagID)        << MethodImpl->getDeclName() << MethodDecl->getReturnType()        << MethodImpl->getReturnType() -      << getTypeRange(MethodImpl->getReturnTypeSourceInfo()); +      << MethodImpl->getReturnTypeSourceRange();    S.Diag(MethodDecl->getLocation(), IsOverridingMode                                          ? diag::note_previous_declaration                                          : diag::note_previous_definition) -      << getTypeRange(MethodDecl->getReturnTypeSourceInfo()); +      << MethodDecl->getReturnTypeSourceRange();    return false;  } @@ -1521,6 +1516,7 @@ static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl,    case OMF_finalize:    case OMF_retainCount:    case OMF_self: +  case OMF_initialize:    case OMF_performSelector:      // Mismatches for these methods don't change ownership      // conventions, so we don't care. @@ -1819,7 +1815,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap,    // Check and see if instance methods in class interface have been    // implemented in the implementation class. If so, their types match.    for (auto *I : CDecl->instance_methods()) { -    if (!InsMapSeen.insert(I->getSelector())) +    if (!InsMapSeen.insert(I->getSelector()).second)        continue;      if (!I->isPropertyAccessor() &&          !InsMap.count(I->getSelector())) { @@ -1846,7 +1842,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap,    // Check and see if class methods in class interface have been    // implemented in the implementation class. If so, their types match.    for (auto *I : CDecl->class_methods()) { -    if (!ClsMapSeen.insert(I->getSelector())) +    if (!ClsMapSeen.insert(I->getSelector()).second)        continue;      if (!ClsMap.count(I->getSelector())) {        if (ImmediateClass) @@ -2008,13 +2004,12 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,                                  IncompleteImpl, InsMap, ClsMap, CDecl,                                  ExplicitImplProtocols);        DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, -                                      /* SynthesizeProperties */ false); +                                      /*SynthesizeProperties=*/false);      }     } else      llvm_unreachable("invalid ObjCContainerDecl type.");  } -/// ActOnForwardClassDeclaration -  Sema::DeclGroupPtrTy  Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,                                     IdentifierInfo **IdentList, @@ -2041,10 +2036,11 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,        } else {          // a forward class declaration matching a typedef name of a class refers          // to the underlying class. Just ignore the forward class with a warning -        // as this will force the intended behavior which is to lookup the typedef -        // name. +        // as this will force the intended behavior which is to lookup the +        // typedef name.          if (isa<ObjCObjectType>(TDD->getUnderlyingType())) { -          Diag(AtClassLoc, diag::warn_forward_class_redefinition) << IdentList[i]; +          Diag(AtClassLoc, diag::warn_forward_class_redefinition) +              << IdentList[i];            Diag(PrevDecl->getLocation(), diag::note_previous_definition);            continue;          } @@ -2107,7 +2103,12 @@ static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,    // validate the basic, low-level compatibility of the two types.    // As a minimum, require the sizes and alignments to match. -  if (Context.getTypeInfo(left) != Context.getTypeInfo(right)) +  TypeInfo LeftTI = Context.getTypeInfo(left); +  TypeInfo RightTI = Context.getTypeInfo(right); +  if (LeftTI.Width != RightTI.Width) +    return false; + +  if (LeftTI.Align != RightTI.Align)      return false;    // Consider all the kinds of non-dependent canonical types: @@ -2159,7 +2160,13 @@ static bool tryMatchRecordTypes(ASTContext &Context,      return false;    // Require size and alignment to match. -  if (Context.getTypeInfo(lt) != Context.getTypeInfo(rt)) return false; +  TypeInfo LeftTI = Context.getTypeInfo(lt); +  TypeInfo RightTI = Context.getTypeInfo(rt); +  if (LeftTI.Width != RightTI.Width) +    return false; + +  if (LeftTI.Align != RightTI.Align) +    return false;    // Require fields to match.    RecordDecl::field_iterator li = left->field_begin(), le = left->field_end(); @@ -2210,21 +2217,22 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,    return true;  } -void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { +void Sema::addMethodToGlobalList(ObjCMethodList *List, +                                 ObjCMethodDecl *Method) {    // Record at the head of the list whether there were 0, 1, or >= 2 methods    // inside categories. -  if (ObjCCategoryDecl * -        CD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) +  if (ObjCCategoryDecl *CD = +          dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()))      if (!CD->IsClassExtension() && List->getBits() < 2) -        List->setBits(List->getBits()+1); +      List->setBits(List->getBits() + 1);    // If the list is empty, make it a singleton list. -  if (List->Method == nullptr) { -    List->Method = Method; +  if (List->getMethod() == nullptr) { +    List->setMethod(Method);      List->setNext(nullptr);      return;    } -   +    // We've seen a method with this name, see if we have already seen this type    // signature.    ObjCMethodList *Previous = List; @@ -2233,35 +2241,42 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {      if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty())        continue; -    if (!MatchTwoMethodDeclarations(Method, List->Method)) +    if (!MatchTwoMethodDeclarations(Method, List->getMethod()))        continue; -     -    ObjCMethodDecl *PrevObjCMethod = List->Method; + +    ObjCMethodDecl *PrevObjCMethod = List->getMethod();      // Propagate the 'defined' bit.      if (Method->isDefined())        PrevObjCMethod->setDefined(true); -     +    else { +      // Objective-C doesn't allow an @interface for a class after its +      // @implementation. So if Method is not defined and there already is +      // an entry for this type signature, Method has to be for a different +      // class than PrevObjCMethod. +      List->setHasMoreThanOneDecl(true); +    } +      // If a method is deprecated, push it in the global pool.      // This is used for better diagnostics.      if (Method->isDeprecated()) {        if (!PrevObjCMethod->isDeprecated()) -        List->Method = Method; +        List->setMethod(Method);      } -    // If new method is unavailable, push it into global pool +    // If the new method is unavailable, push it into global pool      // unless previous one is deprecated.      if (Method->isUnavailable()) {        if (PrevObjCMethod->getAvailability() < AR_Deprecated) -        List->Method = Method; +        List->setMethod(Method);      } -     +      return;    } -   +    // We have a new signature for an existing method - add it.    // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".    ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); -  Previous->setNext(new (Mem) ObjCMethodList(Method, nullptr)); +  Previous->setNext(new (Mem) ObjCMethodList(Method));  }  /// \brief Read the contents of the method pool for a given selector from @@ -2284,7 +2299,7 @@ void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,    if (Pos == MethodPool.end())      Pos = MethodPool.insert(std::make_pair(Method->getSelector(),                                             GlobalMethods())).first; -   +    Method->setDefined(impl);    ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second; @@ -2310,6 +2325,32 @@ static bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen,    return (chosen->getReturnType()->isIntegerType());  } +bool Sema::CollectMultipleMethodsInGlobalPool( +    Selector Sel, SmallVectorImpl<ObjCMethodDecl *> &Methods, bool instance) { +  if (ExternalSource) +    ReadMethodPool(Sel); + +  GlobalMethodPool::iterator Pos = MethodPool.find(Sel); +  if (Pos == MethodPool.end()) +    return false; +  // Gather the non-hidden methods. +  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; +  for (ObjCMethodList *M = &MethList; M; M = M->getNext()) +    if (M->getMethod() && !M->getMethod()->isHidden()) +      Methods.push_back(M->getMethod()); +  return Methods.size() > 1; +} + +bool Sema::AreMultipleMethodsInGlobalPool(Selector Sel, bool instance) { +  GlobalMethodPool::iterator Pos = MethodPool.find(Sel); +  // Test for no method in the pool which should not trigger any warning by +  // caller. +  if (Pos == MethodPool.end()) +    return true; +  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; +  return MethList.hasMoreThanOneDecl(); +} +  ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,                                                 bool receiverIdOrClass,                                                 bool warn, bool instance) { @@ -2324,12 +2365,12 @@ ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,    ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;    SmallVector<ObjCMethodDecl *, 4> Methods;    for (ObjCMethodList *M = &MethList; M; M = M->getNext()) { -    if (M->Method && !M->Method->isHidden()) { +    if (M->getMethod() && !M->getMethod()->isHidden()) {        // If we're not supposed to warn about mismatches, we're done.        if (!warn) -        return M->Method; +        return M->getMethod(); -      Methods.push_back(M->Method); +      Methods.push_back(M->getMethod());      }    } @@ -2401,13 +2442,13 @@ ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {    GlobalMethods &Methods = Pos->second;    for (const ObjCMethodList *Method = &Methods.first; Method;         Method = Method->getNext()) -    if (Method->Method && Method->Method->isDefined()) -      return Method->Method; +    if (Method->getMethod() && Method->getMethod()->isDefined()) +      return Method->getMethod();    for (const ObjCMethodList *Method = &Methods.second; Method;         Method = Method->getNext()) -    if (Method->Method && Method->Method->isDefined()) -      return Method->Method; +    if (Method->getMethod() && Method->getMethod()->isDefined()) +      return Method->getMethod();    return nullptr;  } @@ -2470,25 +2511,27 @@ Sema::SelectorsForTypoCorrection(Selector Sel,         e = MethodPool.end(); b != e; b++) {      // instance methods      for (ObjCMethodList *M = &b->second.first; M; M=M->getNext()) -      if (M->Method && -          (M->Method->getSelector().getNumArgs() == NumArgs) && -          (M->Method->getSelector() != Sel)) { +      if (M->getMethod() && +          (M->getMethod()->getSelector().getNumArgs() == NumArgs) && +          (M->getMethod()->getSelector() != Sel)) {          if (ObjectIsId) -          Methods.push_back(M->Method); +          Methods.push_back(M->getMethod());          else if (!ObjectIsClass && -                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType)) -          Methods.push_back(M->Method); +                 HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), +                                          ObjectType)) +          Methods.push_back(M->getMethod());        }      // class methods      for (ObjCMethodList *M = &b->second.second; M; M=M->getNext()) -      if (M->Method && -          (M->Method->getSelector().getNumArgs() == NumArgs) && -          (M->Method->getSelector() != Sel)) { +      if (M->getMethod() && +          (M->getMethod()->getSelector().getNumArgs() == NumArgs) && +          (M->getMethod()->getSelector() != Sel)) {          if (ObjectIsClass) -          Methods.push_back(M->Method); +          Methods.push_back(M->getMethod());          else if (!ObjectIsId && -                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType)) -          Methods.push_back(M->Method); +                 HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), +                                          ObjectType)) +          Methods.push_back(M->getMethod());        }    } @@ -2818,7 +2861,7 @@ public:      }      ObjCMethodList &list =        method->isInstanceMethod() ? it->second.first : it->second.second; -    if (!list.Method) return; +    if (!list.getMethod()) return;      ObjCContainerDecl *container        = cast<ObjCContainerDecl>(method->getDeclContext()); @@ -3237,6 +3280,7 @@ Decl *Sema::ActOnMethodDeclaration(      case OMF_mutableCopy:      case OMF_release:      case OMF_retainCount: +    case OMF_initialize:      case OMF_performSelector:        break; diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index b92fcbd2a0d9..2387325be435 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -35,6 +35,33 @@ static const FunctionProtoType *GetUnderlyingFunction(QualType T)    return T->getAs<FunctionProtoType>();  } +/// HACK: libstdc++ has a bug where it shadows std::swap with a member +/// swap function then tries to call std::swap unqualified from the exception +/// specification of that function. This function detects whether we're in +/// such a case and turns off delay-parsing of exception specifications. +bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) { +  auto *RD = dyn_cast<CXXRecordDecl>(CurContext); + +  // All the problem cases are member functions named "swap" within class +  // templates declared directly within namespace std. +  if (!RD || RD->getEnclosingNamespaceContext() != getStdNamespace() || +      !RD->getIdentifier() || !RD->getDescribedClassTemplate() || +      !D.getIdentifier() || !D.getIdentifier()->isStr("swap")) +    return false; + +  // Only apply this hack within a system header. +  if (!Context.getSourceManager().isInSystemHeader(D.getLocStart())) +    return false; + +  return llvm::StringSwitch<bool>(RD->getIdentifier()->getName()) +      .Case("array", true) +      .Case("pair", true) +      .Case("priority_queue", true) +      .Case("stack", true) +      .Case("queue", true) +      .Default(false); +} +  /// CheckSpecifiedExceptionType - Check if the given type is valid in an  /// exception specification. Incomplete types, or pointers to incomplete types  /// other than void are not allowed. @@ -112,6 +139,11 @@ bool Sema::CheckDistantExceptionSpec(QualType T) {  const FunctionProtoType *  Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { +  if (FPT->getExceptionSpecType() == EST_Unparsed) { +    Diag(Loc, diag::err_exception_spec_not_parsed); +    return nullptr; +  } +    if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))      return FPT; @@ -132,21 +164,14 @@ Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {    return SourceDecl->getType()->castAs<FunctionProtoType>();  } -void Sema::UpdateExceptionSpec(FunctionDecl *FD, -                               const FunctionProtoType::ExtProtoInfo &EPI) { -  const FunctionProtoType *Proto = FD->getType()->castAs<FunctionProtoType>(); - -  // Overwrite the exception spec and rebuild the function type. -  FunctionProtoType::ExtProtoInfo NewEPI = Proto->getExtProtoInfo(); -  NewEPI.ExceptionSpecType = EPI.ExceptionSpecType; -  NewEPI.NumExceptions = EPI.NumExceptions; -  NewEPI.Exceptions = EPI.Exceptions; -  NewEPI.NoexceptExpr = EPI.NoexceptExpr; -  FD->setType(Context.getFunctionType(Proto->getReturnType(), -                                      Proto->getParamTypes(), NewEPI)); +void +Sema::UpdateExceptionSpec(FunctionDecl *FD, +                          const FunctionProtoType::ExceptionSpecInfo &ESI) { +  for (auto *Redecl : FD->redecls()) +    Context.adjustExceptionSpec(cast<FunctionDecl>(Redecl), ESI);    // If we've fully resolved the exception specification, notify listeners. -  if (!isUnresolvedExceptionSpec(EPI.ExceptionSpecType)) +  if (!isUnresolvedExceptionSpec(ESI.Type))      if (auto *Listener = getASTMutationListener())        Listener->ResolvedExceptionSpec(FD);  } @@ -227,32 +252,28 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {        (Old->getLocation().isInvalid() ||         Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&        Old->isExternC()) { -    FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); -    EPI.ExceptionSpecType = EST_DynamicNone; -    QualType NewType = Context.getFunctionType(NewProto->getReturnType(), -                                               NewProto->getParamTypes(), EPI); -    New->setType(NewType); +    New->setType(Context.getFunctionType( +        NewProto->getReturnType(), NewProto->getParamTypes(), +        NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone)));      return false;    }    const FunctionProtoType *OldProto =      Old->getType()->castAs<FunctionProtoType>(); -  FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); -  EPI.ExceptionSpecType = OldProto->getExceptionSpecType(); -  if (EPI.ExceptionSpecType == EST_Dynamic) { -    EPI.NumExceptions = OldProto->getNumExceptions(); -    EPI.Exceptions = OldProto->exception_begin(); -  } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { +  FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType(); +  if (ESI.Type == EST_Dynamic) { +    ESI.Exceptions = OldProto->exceptions(); +  } else if (ESI.Type == EST_ComputedNoexcept) {      // FIXME: We can't just take the expression from the old prototype. It      // likely contains references to the old prototype's parameters.    }    // Update the type of the function with the appropriate exception    // specification. -  QualType NewType = Context.getFunctionType(NewProto->getReturnType(), -                                             NewProto->getParamTypes(), EPI); -  New->setType(NewType); +  New->setType(Context.getFunctionType( +      NewProto->getReturnType(), NewProto->getParamTypes(), +      NewProto->getExtProtoInfo().withExceptionSpec(ESI)));    // Warn about the lack of exception specification.    SmallString<128> ExceptionSpecString; @@ -723,10 +744,11 @@ static bool CheckSpecForTypesEquivalent(Sema &S,  /// assignment and override compatibility check. We do not check the parameters  /// of parameter function pointers recursively, as no sane programmer would  /// even be able to write such a function type. -bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID, -    const FunctionProtoType *Target, SourceLocation TargetLoc, -    const FunctionProtoType *Source, SourceLocation SourceLoc) -{ +bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &NoteID, +                                   const FunctionProtoType *Target, +                                   SourceLocation TargetLoc, +                                   const FunctionProtoType *Source, +                                   SourceLocation SourceLoc) {    if (CheckSpecForTypesEquivalent(            *this, PDiag(diag::err_deep_exception_specs_differ) << 0, PDiag(),            Target->getReturnType(), TargetLoc, Source->getReturnType(), @@ -747,23 +769,30 @@ bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,    return false;  } -bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) -{ +bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) {    // First we check for applicability.    // Target type must be a function, function pointer or function reference.    const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); -  if (!ToFunc) +  if (!ToFunc || ToFunc->hasDependentExceptionSpec())      return false;    // SourceType must be a function or function pointer.    const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); -  if (!FromFunc) +  if (!FromFunc || FromFunc->hasDependentExceptionSpec())      return false;    // Now we've got the correct types on both sides, check their compatibility.    // This means that the source of the conversion can only throw a subset of    // the exceptions of the target, and any exception specs on arguments or    // return types must be equivalent. +  // +  // FIXME: If there is a nested dependent exception specification, we should +  // not be checking it here. This is fine: +  //   template<typename T> void f() { +  //     void (*p)(void (*) throw(T)); +  //     void (*q)(void (*) throw(int)) = p; +  //   } +  // ... because it might be instantiated with T=int.    return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),                                    PDiag(), ToFunc,                                     From->getSourceRange().getBegin(), @@ -772,6 +801,11 @@ bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)  bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,                                                  const CXXMethodDecl *Old) { +  // If the new exception specification hasn't been parsed yet, skip the check. +  // We'll get called again once it's been parsed. +  if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == +      EST_Unparsed) +    return false;    if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) {      // Don't check uninstantiated template destructors at all. We can only      // synthesize correct specs after the template is instantiated. @@ -780,11 +814,18 @@ bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,      if (New->getParent()->isBeingDefined()) {        // The destructor might be updated once the definition is finished. So        // remember it and check later. -      DelayedDestructorExceptionSpecChecks.push_back(std::make_pair( -        cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old))); +      DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old));        return false;      }    } +  // If the old exception specification hasn't been parsed yet, remember that +  // we need to perform this check when we get to the end of the outermost +  // lexically-surrounding class. +  if (Old->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == +      EST_Unparsed) { +    DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old)); +    return false; +  }    unsigned DiagID = diag::err_override_exception_spec;    if (getLangOpts().MicrosoftExt)      DiagID = diag::ext_override_exception_spec; @@ -1051,6 +1092,7 @@ CanThrowResult Sema::canThrow(const Expr *E) {    case Expr::CXXDependentScopeMemberExprClass:    case Expr::CXXUnresolvedConstructExprClass:    case Expr::DependentScopeDeclRefExprClass: +  case Expr::CXXFoldExprClass:      return CT_Dependent;    case Expr::AsTypeExprClass: @@ -1071,6 +1113,7 @@ CanThrowResult Sema::canThrow(const Expr *E) {    case Expr::UnaryExprOrTypeTraitExprClass:    case Expr::UnresolvedLookupExprClass:    case Expr::UnresolvedMemberExprClass: +  case Expr::TypoExprClass:      // FIXME: Can any of the above throw?  If so, when?      return CT_Cannot; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 35dad82523c9..fba7a2d23ffd 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -42,6 +42,7 @@  #include "clang/Sema/ScopeInfo.h"  #include "clang/Sema/SemaFixItUtils.h"  #include "clang/Sema/Template.h" +#include "llvm/Support/ConvertUTF.h"  using namespace clang;  using namespace sema; @@ -59,7 +60,7 @@ bool Sema::CanUseDecl(NamedDecl *D) {      // If the function has a deduced return type, and we can't deduce it,      // then we can't use it either. -    if (getLangOpts().CPlusPlus1y && FD->getReturnType()->isUndeducedType() && +    if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() &&          DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false))        return false;    } @@ -302,7 +303,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,      // If the function has a deduced return type, and we can't deduce it,      // then we can't use it either. -    if (getLangOpts().CPlusPlus1y && FD->getReturnType()->isUndeducedType() && +    if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() &&          DeduceReturnType(FD, Loc))        return true;    } @@ -397,8 +398,8 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,    if (sentinelExpr->isValueDependent()) return;    if (Context.isSentinelNullExpr(sentinelExpr)) return; -  // Pick a reasonable string to insert.  Optimistically use 'nil' or -  // 'NULL' if those are actually defined in the context.  Only use +  // Pick a reasonable string to insert.  Optimistically use 'nil', 'nullptr', +  // or 'NULL' if those are actually defined in the context.  Only use    // 'nil' for ObjC methods, where it's much more likely that the    // variadic arguments form a list of object pointers.    SourceLocation MissingNilLoc @@ -407,6 +408,8 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,    if (calleeType == CT_Method &&        PP.getIdentifierInfo("nil")->hasMacroDefinition())      NullValue = "nil"; +  else if (getLangOpts().CPlusPlus11) +    NullValue = "nullptr";    else if (PP.getIdentifierInfo("NULL")->hasMacroDefinition())      NullValue = "NULL";    else @@ -800,6 +803,9 @@ Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) {    if (Ty->isObjCObjectType())      return VAK_Invalid; +  if (getLangOpts().MSVCCompat) +    return VAK_MSVCUndefined; +    // FIXME: In C++11, these cases are conditionally-supported, meaning we're    // permitted to reject them. We should consider doing so.    return VAK_Undefined; @@ -829,6 +835,7 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) {      break;    case VAK_Undefined: +  case VAK_MSVCUndefined:      DiagRuntimeBehavior(          E->getLocStart(), nullptr,          PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) @@ -933,68 +940,6 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr,    return false;  } -/// \brief Takes two complex float types and converts them to the same type. -/// Helper function of UsualArithmeticConversions() -static QualType -handleComplexFloatToComplexFloatConverstion(Sema &S, ExprResult &LHS, -                                            ExprResult &RHS, QualType LHSType, -                                            QualType RHSType, -                                            bool IsCompAssign) { -  int order = S.Context.getFloatingTypeOrder(LHSType, RHSType); - -  if (order < 0) { -    // _Complex float -> _Complex double -    if (!IsCompAssign) -      LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingComplexCast); -    return RHSType; -  } -  if (order > 0) -    // _Complex float -> _Complex double -    RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingComplexCast); -  return LHSType; -} - -/// \brief Converts otherExpr to complex float and promotes complexExpr if -/// necessary.  Helper function of UsualArithmeticConversions() -static QualType handleOtherComplexFloatConversion(Sema &S, -                                                  ExprResult &ComplexExpr, -                                                  ExprResult &OtherExpr, -                                                  QualType ComplexTy, -                                                  QualType OtherTy, -                                                  bool ConvertComplexExpr, -                                                  bool ConvertOtherExpr) { -  int order = S.Context.getFloatingTypeOrder(ComplexTy, OtherTy); - -  // If just the complexExpr is complex, the otherExpr needs to be converted, -  // and the complexExpr might need to be promoted. -  if (order > 0) { // complexExpr is wider -    // float -> _Complex double -    if (ConvertOtherExpr) { -      QualType fp = cast<ComplexType>(ComplexTy)->getElementType(); -      OtherExpr = S.ImpCastExprToType(OtherExpr.get(), fp, CK_FloatingCast); -      OtherExpr = S.ImpCastExprToType(OtherExpr.get(), ComplexTy, -                                      CK_FloatingRealToComplex); -    } -    return ComplexTy; -  } - -  // otherTy is at least as wide.  Find its corresponding complex type. -  QualType result = (order == 0 ? ComplexTy : -                                  S.Context.getComplexType(OtherTy)); - -  // double -> _Complex double -  if (ConvertOtherExpr) -    OtherExpr = S.ImpCastExprToType(OtherExpr.get(), result, -                                    CK_FloatingRealToComplex); - -  // _Complex float -> _Complex double -  if (ConvertComplexExpr && order < 0) -    ComplexExpr = S.ImpCastExprToType(ComplexExpr.get(), result, -                                      CK_FloatingComplexCast); - -  return result; -} -  /// \brief Handle arithmetic conversion with complex types.  Helper function of  /// UsualArithmeticConversions()  static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, @@ -1020,26 +965,35 @@ static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS,    // when combining a "long double" with a "double _Complex", the    // "double _Complex" is promoted to "long double _Complex". -  bool LHSComplexFloat = LHSType->isComplexType(); -  bool RHSComplexFloat = RHSType->isComplexType(); - -  // If both are complex, just cast to the more precise type. -  if (LHSComplexFloat && RHSComplexFloat) -    return handleComplexFloatToComplexFloatConverstion(S, LHS, RHS, -                                                       LHSType, RHSType, -                                                       IsCompAssign); - -  // If only one operand is complex, promote it if necessary and convert the -  // other operand to complex. -  if (LHSComplexFloat) -    return handleOtherComplexFloatConversion( -        S, LHS, RHS, LHSType, RHSType, /*convertComplexExpr*/!IsCompAssign, -        /*convertOtherExpr*/ true); - -  assert(RHSComplexFloat); -  return handleOtherComplexFloatConversion( -      S, RHS, LHS, RHSType, LHSType, /*convertComplexExpr*/true, -      /*convertOtherExpr*/ !IsCompAssign); +  // Compute the rank of the two types, regardless of whether they are complex. +  int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType); + +  auto *LHSComplexType = dyn_cast<ComplexType>(LHSType); +  auto *RHSComplexType = dyn_cast<ComplexType>(RHSType); +  QualType LHSElementType = +      LHSComplexType ? LHSComplexType->getElementType() : LHSType; +  QualType RHSElementType = +      RHSComplexType ? RHSComplexType->getElementType() : RHSType; + +  QualType ResultType = S.Context.getComplexType(LHSElementType); +  if (Order < 0) { +    // Promote the precision of the LHS if not an assignment. +    ResultType = S.Context.getComplexType(RHSElementType); +    if (!IsCompAssign) { +      if (LHSComplexType) +        LHS = +            S.ImpCastExprToType(LHS.get(), ResultType, CK_FloatingComplexCast); +      else +        LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast); +    } +  } else if (Order > 0) { +    // Promote the precision of the RHS. +    if (RHSComplexType) +      RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast); +    else +      RHS = S.ImpCastExprToType(RHS.get(), LHSElementType, CK_FloatingCast); +  } +  return ResultType;  }  /// \brief Hande arithmetic conversion from integer to float.  Helper function @@ -1336,6 +1290,13 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,      ControllingExpr = result.get();    } +  // The controlling expression is an unevaluated operand, so side effects are +  // likely unintended. +  if (ActiveTemplateInstantiations.empty() && +      ControllingExpr->HasSideEffects(Context, false)) +    Diag(ControllingExpr->getExprLoc(), +         diag::warn_side_effects_unevaluated_context); +    bool TypeErrorFound = false,         IsResultDependent = ControllingExpr->isTypeDependent(),         ContainsUnexpandedParameterPack @@ -1636,40 +1597,37 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,    if (getLangOpts().CUDA)      if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext))        if (const FunctionDecl *Callee = dyn_cast<FunctionDecl>(D)) { -        CUDAFunctionTarget CallerTarget = IdentifyCUDATarget(Caller), -                           CalleeTarget = IdentifyCUDATarget(Callee); -        if (CheckCUDATarget(CallerTarget, CalleeTarget)) { +        if (CheckCUDATarget(Caller, Callee)) {            Diag(NameInfo.getLoc(), diag::err_ref_bad_target) -            << CalleeTarget << D->getIdentifier() << CallerTarget; +            << IdentifyCUDATarget(Callee) << D->getIdentifier() +            << IdentifyCUDATarget(Caller);            Diag(D->getLocation(), diag::note_previous_decl)              << D->getIdentifier();            return ExprError();          }        } -  bool refersToEnclosingScope = -    (CurContext != D->getDeclContext() && -     D->getDeclContext()->isFunctionOrMethod()) || -    (isa<VarDecl>(D) && -     cast<VarDecl>(D)->isInitCapture()); +  bool RefersToCapturedVariable = +      isa<VarDecl>(D) && +      NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc());    DeclRefExpr *E;    if (isa<VarTemplateSpecializationDecl>(D)) {      VarTemplateSpecializationDecl *VarSpec =          cast<VarTemplateSpecializationDecl>(D); -    E = DeclRefExpr::Create( -        Context, -        SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(), -        VarSpec->getTemplateKeywordLoc(), D, refersToEnclosingScope, -        NameInfo.getLoc(), Ty, VK, FoundD, TemplateArgs); +    E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context) +                                        : NestedNameSpecifierLoc(), +                            VarSpec->getTemplateKeywordLoc(), D, +                            RefersToCapturedVariable, NameInfo.getLoc(), Ty, VK, +                            FoundD, TemplateArgs);    } else {      assert(!TemplateArgs && "No template arguments for non-variable"                              " template specialization references"); -    E = DeclRefExpr::Create( -        Context, -        SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(), -        SourceLocation(), D, refersToEnclosingScope, NameInfo, Ty, VK, FoundD); +    E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context) +                                        : NestedNameSpecifierLoc(), +                            SourceLocation(), D, RefersToCapturedVariable, +                            NameInfo, Ty, VK, FoundD);    }    MarkDeclRefReferenced(E); @@ -1719,13 +1677,48 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,    }  } +static void emitEmptyLookupTypoDiagnostic( +    const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS, +    DeclarationName Typo, SourceLocation TypoLoc, ArrayRef<Expr *> Args, +    unsigned DiagnosticID, unsigned DiagnosticSuggestID) { +  DeclContext *Ctx = +      SS.isEmpty() ? nullptr : SemaRef.computeDeclContext(SS, false); +  if (!TC) { +    // Emit a special diagnostic for failed member lookups. +    // FIXME: computing the declaration context might fail here (?) +    if (Ctx) +      SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx +                                                 << SS.getRange(); +    else +      SemaRef.Diag(TypoLoc, DiagnosticID) << Typo; +    return; +  } + +  std::string CorrectedStr = TC.getAsString(SemaRef.getLangOpts()); +  bool DroppedSpecifier = +      TC.WillReplaceSpecifier() && Typo.getAsString() == CorrectedStr; +  unsigned NoteID = +      (TC.getCorrectionDecl() && isa<ImplicitParamDecl>(TC.getCorrectionDecl())) +          ? diag::note_implicit_param_decl +          : diag::note_previous_decl; +  if (!Ctx) +    SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo, +                         SemaRef.PDiag(NoteID)); +  else +    SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) +                                 << Typo << Ctx << DroppedSpecifier +                                 << SS.getRange(), +                         SemaRef.PDiag(NoteID)); +} +  /// Diagnose an empty lookup.  ///  /// \return false if new lookup candidates were found -bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, -                               CorrectionCandidateCallback &CCC, -                               TemplateArgumentListInfo *ExplicitTemplateArgs, -                               ArrayRef<Expr *> Args) { +bool +Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, +                          std::unique_ptr<CorrectionCandidateCallback> CCC, +                          TemplateArgumentListInfo *ExplicitTemplateArgs, +                          ArrayRef<Expr *> Args, TypoExpr **Out) {    DeclarationName Name = R.getLookupName();    unsigned diagnostic = diag::err_undeclared_var_use; @@ -1842,8 +1835,22 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,    // We didn't find anything, so try to correct for a typo.    TypoCorrection Corrected; -  if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), -                                    S, &SS, CCC, CTK_ErrorRecovery))) { +  if (S && Out) { +    SourceLocation TypoLoc = R.getNameLoc(); +    assert(!ExplicitTemplateArgs && +           "Diagnosing an empty lookup with explicit template args!"); +    *Out = CorrectTypoDelayed( +        R.getLookupNameInfo(), R.getLookupKind(), S, &SS, std::move(CCC), +        [=](const TypoCorrection &TC) { +          emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args, +                                        diagnostic, diagnostic_suggest); +        }, +        nullptr, CTK_ErrorRecovery); +    if (*Out) +      return true; +  } else if (S && (Corrected = +                       CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, +                                   &SS, std::move(CCC), CTK_ErrorRecovery))) {      std::string CorrectedStr(Corrected.getAsString(getLangOpts()));      bool DroppedSpecifier =          Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; @@ -1990,14 +1997,12 @@ recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context,        TemplateArgs);  } -ExprResult Sema::ActOnIdExpression(Scope *S, -                                   CXXScopeSpec &SS, -                                   SourceLocation TemplateKWLoc, -                                   UnqualifiedId &Id, -                                   bool HasTrailingLParen, -                                   bool IsAddressOfOperand, -                                   CorrectionCandidateCallback *CCC, -                                   bool IsInlineAsmIdentifier) { +ExprResult +Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, +                        SourceLocation TemplateKWLoc, UnqualifiedId &Id, +                        bool HasTrailingLParen, bool IsAddressOfOperand, +                        std::unique_ptr<CorrectionCandidateCallback> CCC, +                        bool IsInlineAsmIdentifier, Token *KeywordReplacement) {    assert(!(IsAddressOfOperand && HasTrailingLParen) &&           "cannot be direct & operand and have a trailing lparen");    if (SS.isInvalid()) @@ -2109,12 +2114,43 @@ ExprResult Sema::ActOnIdExpression(Scope *S,      // If this name wasn't predeclared and if this is not a function      // call, diagnose the problem. -    CorrectionCandidateCallback DefaultValidator; -    DefaultValidator.IsAddressOfOperand = IsAddressOfOperand; +    TypoExpr *TE = nullptr; +    auto DefaultValidator = llvm::make_unique<CorrectionCandidateCallback>( +        II, SS.isValid() ? SS.getScopeRep() : nullptr); +    DefaultValidator->IsAddressOfOperand = IsAddressOfOperand;      assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&             "Typo correction callback misconfigured"); -    if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator)) -      return ExprError(); +    if (CCC) { +      // Make sure the callback knows what the typo being diagnosed is. +      CCC->setTypoName(II); +      if (SS.isValid()) +        CCC->setTypoNNS(SS.getScopeRep()); +    } +    if (DiagnoseEmptyLookup(S, SS, R, +                            CCC ? std::move(CCC) : std::move(DefaultValidator), +                            nullptr, None, &TE)) { +      if (TE && KeywordReplacement) { +        auto &State = getTypoExprState(TE); +        auto BestTC = State.Consumer->getNextCorrection(); +        if (BestTC.isKeyword()) { +          auto *II = BestTC.getCorrectionAsIdentifierInfo(); +          if (State.DiagHandler) +            State.DiagHandler(BestTC); +          KeywordReplacement->startToken(); +          KeywordReplacement->setKind(II->getTokenID()); +          KeywordReplacement->setIdentifierInfo(II); +          KeywordReplacement->setLocation(BestTC.getCorrectionRange().getBegin()); +          // Clean up the state associated with the TypoExpr, since it has +          // now been diagnosed (without a call to CorrectDelayedTyposInExpr). +          clearDelayedTypo(TE); +          // Signal that a correction to a keyword was performed by returning a +          // valid-but-null ExprResult. +          return (Expr*)nullptr; +        } +        State.Consumer->resetCorrectionStream(); +      } +      return TE ? TE : ExprError(); +    }      assert(!R.empty() &&             "DiagnoseEmptyLookup returned false but added no results"); @@ -2364,10 +2400,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,            !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV))          Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); -      ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(), -                                                              Loc, IV->getLocation(), -                                                              SelfExpr.get(), -                                                              true, true); +      ObjCIvarRefExpr *Result = new (Context) +          ObjCIvarRefExpr(IV, IV->getType(), Loc, IV->getLocation(), +                          SelfExpr.get(), true, true);        if (getLangOpts().ObjCAutoRefCount) {          if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { @@ -2660,15 +2695,15 @@ static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {    return false;  } -ExprResult -Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, -                               LookupResult &R, -                               bool NeedsADL) { +ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, +                                          LookupResult &R, bool NeedsADL, +                                          bool AcceptInvalidDecl) {    // If this is a single, fully-resolved result and we don't need ADL,    // just build an ordinary singleton decl ref.    if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>())      return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(), -                                    R.getRepresentativeDecl()); +                                    R.getRepresentativeDecl(), nullptr, +                                    AcceptInvalidDecl);    // We only need to check the declaration if there's exactly one    // result, because in the overloaded case the results can only be @@ -2695,7 +2730,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,  /// \brief Complete semantic analysis for a reference to the given declaration.  ExprResult Sema::BuildDeclarationNameExpr(      const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, -    NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs) { +    NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, +    bool AcceptInvalidDecl) {    assert(D && "Cannot refer to a NULL declaration");    assert(!isa<FunctionTemplateDecl>(D) &&           "Cannot refer unambiguously to a function template"); @@ -2730,7 +2766,7 @@ ExprResult Sema::BuildDeclarationNameExpr(      return ExprError();    // Only create DeclRefExpr's for valid Decl's. -  if (VD->isInvalidDecl()) +  if (VD->isInvalidDecl() && !AcceptInvalidDecl)      return ExprError();    // Handle members of anonymous structs and unions.  If we got here, @@ -2902,6 +2938,17 @@ ExprResult Sema::BuildDeclarationNameExpr(    }  } +static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source, +                                    SmallString<32> &Target) { +  Target.resize(CharByteWidth * (Source.size() + 1)); +  char *ResultPtr = &Target[0]; +  const UTF8 *ErrorPtr; +  bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr, ErrorPtr); +  (void)success; +  assert(success); +  Target.resize(ResultPtr - &Target[0]); +} +  ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,                                       PredefinedExpr::IdentType IT) {    // Pick the current block, lambda, captured statement or function. @@ -2921,22 +2968,35 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,    }    QualType ResTy; +  StringLiteral *SL = nullptr;    if (cast<DeclContext>(currentDecl)->isDependentContext())      ResTy = Context.DependentTy;    else {      // Pre-defined identifiers are of type char[x], where x is the length of      // the string. -    unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length(); +    auto Str = PredefinedExpr::ComputeName(IT, currentDecl); +    unsigned Length = Str.length();      llvm::APInt LengthI(32, Length + 1); -    if (IT == PredefinedExpr::LFunction) +    if (IT == PredefinedExpr::LFunction) {        ResTy = Context.WideCharTy.withConst(); -    else +      SmallString<32> RawChars; +      ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(), +                              Str, RawChars); +      ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, +                                           /*IndexTypeQuals*/ 0); +      SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide, +                                 /*Pascal*/ false, ResTy, Loc); +    } else {        ResTy = Context.CharTy.withConst(); -    ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0); +      ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, +                                           /*IndexTypeQuals*/ 0); +      SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii, +                                 /*Pascal*/ false, ResTy, Loc); +    }    } -  return new (Context) PredefinedExpr(Loc, ResTy, IT); +  return new (Context) PredefinedExpr(Loc, ResTy, IT, SL);  }  ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { @@ -3046,6 +3106,34 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,    return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc);  } +bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) { +  assert(E && "Invalid expression"); + +  if (E->isValueDependent()) +    return false; + +  QualType QT = E->getType(); +  if (!QT->isIntegerType() || QT->isBooleanType() || QT->isCharType()) { +    Diag(E->getExprLoc(), diag::err_pragma_loop_invalid_argument_type) << QT; +    return true; +  } + +  llvm::APSInt ValueAPS; +  ExprResult R = VerifyIntegerConstantExpression(E, &ValueAPS); + +  if (R.isInvalid()) +    return true; + +  bool ValueIsPositive = ValueAPS.isStrictlyPositive(); +  if (!ValueIsPositive || ValueAPS.getActiveBits() > 31) { +    Diag(E->getExprLoc(), diag::err_pragma_loop_invalid_argument_value) +        << ValueAPS.toString(10) << ValueIsPositive; +    return true; +  } + +  return false; +} +  ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {    // Fast path for a single digit (which is quite common).  A single digit    // cannot have a trigraph, escaped newline, radix prefix, or suffix. @@ -3117,7 +3205,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {        } else {          llvm::APInt ResultVal(Context.getTargetInfo().getLongLongWidth(), 0);          if (Literal.GetIntegerValue(ResultVal)) -          Diag(Tok.getLocation(), diag::err_integer_too_large); +          Diag(Tok.getLocation(), diag::err_integer_literal_too_large) +              << /* Unsigned */ 1;          Lit = IntegerLiteral::Create(Context, ResultVal, CookedTy,                                       Tok.getLocation());        } @@ -3210,7 +3299,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {      if (Literal.GetIntegerValue(ResultVal)) {        // If this value didn't fit into uintmax_t, error and force to ull. -      Diag(Tok.getLocation(), diag::err_integer_too_large); +      Diag(Tok.getLocation(), diag::err_integer_literal_too_large) +          << /* Unsigned */ 1;        Ty = Context.UnsignedLongLongTy;        assert(Context.getTypeSize(Ty) == ResultVal.getBitWidth() &&               "long long is not intmax_t?"); @@ -3290,7 +3380,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {        // If we still couldn't decide a type, we probably have something that        // does not fit in a signed long long, but has no U suffix.        if (Ty.isNull()) { -        Diag(Tok.getLocation(), diag::ext_integer_too_large_for_signed); +        Diag(Tok.getLocation(), diag::ext_integer_literal_too_large_for_signed);          Ty = Context.UnsignedLongLongTy;          Width = Context.getTargetInfo().getLongLongWidth();        } @@ -3442,6 +3532,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,      return true;    } +  // The operand for sizeof and alignof is in an unevaluated expression context, +  // so side effects could result in unintended consequences. +  if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf) && +      ActiveTemplateInstantiations.empty() && E->HasSideEffects(Context, false)) +    Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context); +    if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(),                                         E->getSourceRange(), ExprKind))      return true; @@ -4083,11 +4179,12 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn,    MemberExpr *ME = dyn_cast<MemberExpr>(Fn);    DeclarationName FuncName = FDecl->getDeclName();    SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart(); -  FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME);    if (TypoCorrection Corrected = S.CorrectTypo(            DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName, -          S.getScopeForContext(S.CurContext), nullptr, CCC, +          S.getScopeForContext(S.CurContext), nullptr, +          llvm::make_unique<FunctionCallCCC>(S, FuncName.getAsIdentifierInfo(), +                                             Args.size(), ME),            Sema::CTK_ErrorRecovery)) {      if (NamedDecl *ND = Corrected.getCorrectionDecl()) {        if (Corrected.isOverloaded()) { @@ -4454,6 +4551,8 @@ static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) {        ExprResult result = S.CheckPlaceholderExpr(args[i]);        if (result.isInvalid()) hasInvalid = true;        else args[i] = result.get(); +    } else if (hasInvalid) { +      (void)S.CorrectDelayedTyposInExpr(args[i]);      }    }    return hasInvalid; @@ -4587,23 +4686,6 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,                                 ExecConfig, IsExecConfig);  } -ExprResult -Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, -                              MultiExprArg ExecConfig, SourceLocation GGGLoc) { -  FunctionDecl *ConfigDecl = Context.getcudaConfigureCallDecl(); -  if (!ConfigDecl) -    return ExprError(Diag(LLLLoc, diag::err_undeclared_var_use) -                          << "cudaConfigureCall"); -  QualType ConfigQTy = ConfigDecl->getType(); - -  DeclRefExpr *ConfigDR = new (Context) DeclRefExpr( -      ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc); -  MarkFunctionReferenced(LLLLoc, ConfigDecl); - -  return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, nullptr, -                       /*IsExecConfig=*/true); -} -  /// ActOnAsTypeExpr - create a new asType (bitcast) from the arguments.  ///  /// __builtin_astype( value, dst type ) @@ -4680,8 +4762,12 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,                                       VK_RValue, RParenLoc);    // Bail out early if calling a builtin with custom typechecking. -  if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) -    return CheckBuiltinFunctionCall(BuiltinID, TheCall); +  if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) { +    ExprResult Res = CorrectDelayedTyposInExpr(TheCall); +    if (!Res.isUsable() || !isa<CallExpr>(Res.get())) +      return Res; +    return CheckBuiltinFunctionCall(FDecl, BuiltinID, cast<CallExpr>(Res.get())); +  }   retry:    const FunctionType *FuncT; @@ -4809,7 +4895,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,        return ExprError();      if (BuiltinID) -      return CheckBuiltinFunctionCall(BuiltinID, TheCall); +      return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);    } else if (NDecl) {      if (CheckPointerCall(NDecl, TheCall, Proto))        return ExprError(); @@ -5227,6 +5313,12 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,    if (getLangOpts().CPlusPlus) {      // Check that there are no default arguments (C++ only).      CheckExtraCXXDefaultArguments(D); +  } else { +    // Make sure any TypoExprs have been dealt with. +    ExprResult Res = CorrectDelayedTyposInExpr(CastExpr); +    if (!Res.isUsable()) +      return ExprError(); +    CastExpr = Res.get();    }    checkUnusedDeclAttributes(D); @@ -5693,6 +5785,15 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,                                          ExprObjectKind &OK,                                          SourceLocation QuestionLoc) { +  if (!getLangOpts().CPlusPlus) { +    // C cannot handle TypoExpr nodes on either side of a binop because it +    // doesn't handle dependent types properly, so make sure any TypoExprs have +    // been dealt with before checking the operands. +    ExprResult CondResult = CorrectDelayedTyposInExpr(Cond); +    if (!CondResult.isUsable()) return QualType(); +    Cond = CondResult; +  } +    ExprResult LHSResult = CheckPlaceholderExpr(LHS.get());    if (!LHSResult.isUsable()) return QualType();    LHS = LHSResult; @@ -5720,7 +5821,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,        RHS.get()->getType()->isVectorType())      return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); -  UsualArithmeticConversions(LHS, RHS); +  QualType ResTy = UsualArithmeticConversions(LHS, RHS);    if (LHS.isInvalid() || RHS.isInvalid())      return QualType(); @@ -5737,8 +5838,12 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,    // If both operands have arithmetic type, do the usual arithmetic conversions    // to find a common type: C99 6.5.15p3,5. -  if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) -    return LHS.get()->getType(); +  if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) { +    LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); +    RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy)); + +    return ResTy; +  }    // If both operands are the same structure or union type, the result is that    // type. @@ -6161,7 +6266,7 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) {    if (!lhq.compatiblyIncludes(rhq)) {      // Treat address-space mismatches as fatal.  TODO: address subspaces -    if (lhq.getAddressSpace() != rhq.getAddressSpace()) +    if (!lhq.isAddressSpaceSupersetOf(rhq))        ConvTy = Sema::IncompatiblePointerDiscardsQualifiers;      // It's okay to add or remove GC or lifetime qualifiers when converting to @@ -6446,7 +6551,9 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,    if (const PointerType *LHSPointer = dyn_cast<PointerType>(LHSType)) {      // U* -> T*      if (isa<PointerType>(RHSType)) { -      Kind = CK_BitCast; +      unsigned AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); +      unsigned AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); +      Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;        return checkPointerTypesForAssignment(*this, LHSType, RHSType);      } @@ -6754,6 +6861,15 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS,        return Incompatible;    } +  Expr *PRE = RHS.get()->IgnoreParenCasts(); +  if (ObjCProtocolExpr *OPE = dyn_cast<ObjCProtocolExpr>(PRE)) { +    ObjCProtocolDecl *PDecl = OPE->getProtocol(); +    if (PDecl && !PDecl->hasDefinition()) { +      Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl->getName(); +      Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl; +    } +  } +      CastKind Kind = CK_Invalid;    Sema::AssignConvertType result =      CheckAssignmentConstraints(LHSType, RHS, Kind); @@ -7120,6 +7236,19 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,    if (isLHSPointer) LHSPointeeTy = LHSExpr->getType()->getPointeeType();    if (isRHSPointer) RHSPointeeTy = RHSExpr->getType()->getPointeeType(); +  // if both are pointers check if operation is valid wrt address spaces +  if (isLHSPointer && isRHSPointer) { +    const PointerType *lhsPtr = LHSExpr->getType()->getAs<PointerType>(); +    const PointerType *rhsPtr = RHSExpr->getType()->getAs<PointerType>(); +    if (!lhsPtr->isAddressSpaceOverlapping(*rhsPtr)) { +      S.Diag(Loc, +             diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) +          << LHSExpr->getType() << RHSExpr->getType() << 1 /*arithmetic op*/ +          << LHSExpr->getSourceRange() << RHSExpr->getSourceRange(); +      return false; +    } +  } +    // Check for arithmetic on pointers to incomplete types.    bool isLHSVoidPtr = isLHSPointer && LHSPointeeTy->isVoidType();    bool isRHSVoidPtr = isRHSPointer && RHSPointeeTy->isVoidType(); @@ -7163,7 +7292,7 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,    bool IsStringPlusInt = StrExpr &&        IndexExpr->getType()->isIntegralOrUnscopedEnumerationType(); -  if (!IsStringPlusInt) +  if (!IsStringPlusInt || IndexExpr->isValueDependent())      return;    llvm::APSInt index; @@ -7193,13 +7322,13 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,  /// \brief Emit a warning when adding a char literal to a string.  static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc,                                     Expr *LHSExpr, Expr *RHSExpr) { -  const DeclRefExpr *StringRefExpr = -      dyn_cast<DeclRefExpr>(LHSExpr->IgnoreImpCasts()); +  const Expr *StringRefExpr = LHSExpr;    const CharacterLiteral *CharExpr =        dyn_cast<CharacterLiteral>(RHSExpr->IgnoreImpCasts()); -  if (!StringRefExpr) { -    StringRefExpr = dyn_cast<DeclRefExpr>(RHSExpr->IgnoreImpCasts()); + +  if (!CharExpr) {      CharExpr = dyn_cast<CharacterLiteral>(LHSExpr->IgnoreImpCasts()); +    StringRefExpr = RHSExpr;    }    if (!CharExpr || !StringRefExpr) @@ -7417,7 +7546,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,  }  static bool isScopedEnumerationType(QualType T) { -  if (const EnumType *ET = dyn_cast<EnumType>(T)) +  if (const EnumType *ET = T->getAs<EnumType>())      return ET->getDecl()->isScoped();    return false;  } @@ -8048,6 +8177,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,        diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false);      }      if (LCanPointeeTy != RCanPointeeTy) { +      const PointerType *lhsPtr = LHSType->getAs<PointerType>(); +      if (!lhsPtr->isAddressSpaceOverlapping(*RHSType->getAs<PointerType>())) { +        Diag(Loc, +             diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) +            << LHSType << RHSType << 0 /* comparison */ +            << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); +      }        unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace();        unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace();        CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion @@ -8462,7 +8598,7 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {    // Must be a reference to a declaration from an enclosing scope.    DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);    if (!DRE) return NCCK_None; -  if (!DRE->refersToEnclosingLocal()) return NCCK_None; +  if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None;    // The declaration must be a variable which is not declared 'const'.    VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl()); @@ -8494,19 +8630,19 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {    if (IsLV == Expr::MLV_Valid)      return false; -  unsigned Diag = 0; +  unsigned DiagID = 0;    bool NeedType = false;    switch (IsLV) { // C99 6.5.16p2    case Expr::MLV_ConstQualified: -    Diag = diag::err_typecheck_assign_const; +    DiagID = diag::err_typecheck_assign_const;      // Use a specialized diagnostic when we're assigning to an object      // from an enclosing function or block.      if (NonConstCaptureKind NCCK = isReferenceToNonConstCapture(S, E)) {        if (NCCK == NCCK_Block) -        Diag = diag::err_block_decl_ref_not_modifiable_lvalue; +        DiagID = diag::err_block_decl_ref_not_modifiable_lvalue;        else -        Diag = diag::err_lambda_decl_ref_not_modifiable_lvalue; +        DiagID = diag::err_lambda_decl_ref_not_modifiable_lvalue;        break;      } @@ -8526,18 +8662,18 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {            //  - self            ObjCMethodDecl *method = S.getCurMethodDecl();            if (method && var == method->getSelfDecl()) -            Diag = method->isClassMethod() +            DiagID = method->isClassMethod()                ? diag::err_typecheck_arc_assign_self_class_method                : diag::err_typecheck_arc_assign_self;            //  - fast enumeration variables            else -            Diag = diag::err_typecheck_arr_assign_enumeration; +            DiagID = diag::err_typecheck_arr_assign_enumeration;            SourceRange Assign;            if (Loc != OrigLoc)              Assign = SourceRange(OrigLoc, OrigLoc); -          S.Diag(Loc, Diag) << E->getSourceRange() << Assign; +          S.Diag(Loc, DiagID) << E->getSourceRange() << Assign;            // We need to preserve the AST regardless, so migration tool             // can do its job.            return false; @@ -8548,37 +8684,37 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {      break;    case Expr::MLV_ArrayType:    case Expr::MLV_ArrayTemporary: -    Diag = diag::err_typecheck_array_not_modifiable_lvalue; +    DiagID = diag::err_typecheck_array_not_modifiable_lvalue;      NeedType = true;      break;    case Expr::MLV_NotObjectType: -    Diag = diag::err_typecheck_non_object_not_modifiable_lvalue; +    DiagID = diag::err_typecheck_non_object_not_modifiable_lvalue;      NeedType = true;      break;    case Expr::MLV_LValueCast: -    Diag = diag::err_typecheck_lvalue_casts_not_supported; +    DiagID = diag::err_typecheck_lvalue_casts_not_supported;      break;    case Expr::MLV_Valid:      llvm_unreachable("did not take early return for MLV_Valid");    case Expr::MLV_InvalidExpression:    case Expr::MLV_MemberFunction:    case Expr::MLV_ClassTemporary: -    Diag = diag::err_typecheck_expression_not_modifiable_lvalue; +    DiagID = diag::err_typecheck_expression_not_modifiable_lvalue;      break;    case Expr::MLV_IncompleteType:    case Expr::MLV_IncompleteVoidType:      return S.RequireCompleteType(Loc, E->getType(),               diag::err_typecheck_incomplete_type_not_modifiable_lvalue, E);    case Expr::MLV_DuplicateVectorComponents: -    Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue; +    DiagID = diag::err_typecheck_duplicate_vector_components_not_mlvalue;      break;    case Expr::MLV_NoSetterProperty:      llvm_unreachable("readonly properties should be processed differently");    case Expr::MLV_InvalidMessageExpression: -    Diag = diag::error_readonly_message_assignment; +    DiagID = diag::error_readonly_message_assignment;      break;    case Expr::MLV_SubObjCPropertySetting: -    Diag = diag::error_no_subobject_property_setting; +    DiagID = diag::error_no_subobject_property_setting;      break;    } @@ -8586,9 +8722,9 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {    if (Loc != OrigLoc)      Assign = SourceRange(OrigLoc, OrigLoc);    if (NeedType) -    S.Diag(Loc, Diag) << E->getType() << E->getSourceRange() << Assign; +    S.Diag(Loc, DiagID) << E->getType() << E->getSourceRange() << Assign;    else -    S.Diag(Loc, Diag) << E->getSourceRange() << Assign; +    S.Diag(Loc, DiagID) << E->getSourceRange() << Assign;    return true;  } @@ -8754,6 +8890,7 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,  /// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.  static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,                                                 ExprValueKind &VK, +                                               ExprObjectKind &OK,                                                 SourceLocation OpLoc,                                                 bool IsInc, bool IsPrefix) {    if (Op->isTypeDependent()) @@ -8799,7 +8936,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,    } else if (ResType->isPlaceholderType()) {      ExprResult PR = S.CheckPlaceholderExpr(Op);      if (PR.isInvalid()) return QualType(); -    return CheckIncrementDecrementOperand(S, PR.get(), VK, OpLoc, +    return CheckIncrementDecrementOperand(S, PR.get(), VK, OK, OpLoc,                                            IsInc, IsPrefix);    } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) {      // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) @@ -8820,6 +8957,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,    // operand.    if (IsPrefix && S.getLangOpts().CPlusPlus) {      VK = VK_LValue; +    OK = Op->getObjectKind();      return ResType;    } else {      VK = VK_RValue; @@ -9104,6 +9242,24 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {    return Context.getPointerType(op->getType());  } +static void RecordModifiableNonNullParam(Sema &S, const Expr *Exp) { +  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp); +  if (!DRE) +    return; +  const Decl *D = DRE->getDecl(); +  if (!D) +    return; +  const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D); +  if (!Param) +    return; +  if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(Param->getDeclContext())) +    if (!FD->hasAttr<NonNullAttr>() && !Param->hasAttr<NonNullAttr>()) +      return; +  if (FunctionScopeInfo *FD = S.getCurFunction()) +    if (!FD->ModifiedNonNullParams.count(Param)) +      FD->ModifiedNonNullParams.insert(Param); +} +  /// CheckIndirectionOperand - Type check unary indirection (prefix '*').  static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,                                          SourceLocation OpLoc) { @@ -9164,8 +9320,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,    return Result;  } -static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode( -  tok::TokenKind Kind) { +BinaryOperatorKind Sema::ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind) {    BinaryOperatorKind Opc;    switch (Kind) {    default: llvm_unreachable("Unknown binop!"); @@ -9334,6 +9489,16 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,    ExprValueKind VK = VK_RValue;    ExprObjectKind OK = OK_Ordinary; +  if (!getLangOpts().CPlusPlus) { +    // C cannot handle TypoExpr nodes on either side of a binop because it +    // doesn't handle dependent types properly, so make sure any TypoExprs have +    // been dealt with before checking the operands. +    LHS = CorrectDelayedTyposInExpr(LHSExpr); +    RHS = CorrectDelayedTyposInExpr(RHSExpr); +    if (!LHS.isUsable() || !RHS.isUsable()) +      return ExprError(); +  } +    switch (Opc) {    case BO_Assign:      ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType()); @@ -9342,8 +9507,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,        VK = LHS.get()->getValueKind();        OK = LHS.get()->getObjectKind();      } -    if (!ResultTy.isNull()) +    if (!ResultTy.isNull()) {        DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); +      DiagnoseSelfMove(LHS.get(), RHS.get(), OpLoc); +    } +    RecordModifiableNonNullParam(*this, LHS.get());      break;    case BO_PtrMemD:    case BO_PtrMemI: @@ -9503,7 +9671,7 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,    StringRef OpStr = isLeftComp ? LHSBO->getOpcodeStr() : RHSBO->getOpcodeStr();    SourceRange ParensRange = isLeftComp ?        SourceRange(LHSBO->getRHS()->getLocStart(), RHSExpr->getLocEnd()) -    : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocStart()); +    : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocEnd());    Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel)      << DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr; @@ -9709,7 +9877,7 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc,    UnresolvedSet<16> Functions;    OverloadedOperatorKind OverOp      = BinaryOperator::getOverloadedOperator(Opc); -  if (Sc && OverOp != OO_None) +  if (Sc && OverOp != OO_None && OverOp != OO_Equal)      S.LookupOverloadedOperatorName(OverOp, Sc, LHS->getType(),                                     RHS->getType(), Functions); @@ -9808,7 +9976,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,    case UO_PreDec:    case UO_PostInc:    case UO_PostDec: -    resultType = CheckIncrementDecrementOperand(*this, Input.get(), VK, OpLoc, +    resultType = CheckIncrementDecrementOperand(*this, Input.get(), VK, OK, +                                                OpLoc,                                                  Opc == UO_PreInc ||                                                  Opc == UO_PostInc,                                                  Opc == UO_PreInc || @@ -9816,6 +9985,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,      break;    case UO_AddrOf:      resultType = CheckAddressOfOperand(Input, OpLoc); +    RecordModifiableNonNullParam(*this, InputExpr);      break;    case UO_Deref: {      Input = DefaultFunctionArrayLvalueConversion(Input.get()); @@ -10107,11 +10277,6 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,    assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");    PopExpressionEvaluationContext(); -  bool isFileScope -    = (getCurFunctionOrMethodDecl() == nullptr) && (getCurBlock() == nullptr); -  if (isFileScope) -    return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope)); -    // FIXME: there are a variety of strange constraints to enforce here, for    // example, it is not possible to goto into a stmt expression apparently.    // More semantic analysis is needed. @@ -10998,7 +11163,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,    PartialDiagnostic FDiag = PDiag(DiagKind);    if (Action == AA_Passing_CFAudited) -    FDiag << FirstType << SecondType << SrcExpr->getSourceRange(); +    FDiag << FirstType << SecondType << AA_Passing << SrcExpr->getSourceRange();    else      FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange(); @@ -11285,6 +11450,7 @@ Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,  void Sema::PopExpressionEvaluationContext() {    ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); +  unsigned NumTypos = Rec.NumTypos;    if (!Rec.Lambdas.empty()) {      if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) { @@ -11301,19 +11467,14 @@ void Sema::PopExpressionEvaluationContext() {          //   evaluate [...] a lambda-expression.          D = diag::err_lambda_in_constant_expression;        } -      for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) -        Diag(Rec.Lambdas[I]->getLocStart(), D); +      for (const auto *L : Rec.Lambdas) +        Diag(L->getLocStart(), D);      } else {        // Mark the capture expressions odr-used. This was deferred        // during lambda expression creation. -      for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) { -        LambdaExpr *Lambda = Rec.Lambdas[I]; -        for (LambdaExpr::capture_init_iterator  -                  C = Lambda->capture_init_begin(), -               CEnd = Lambda->capture_init_end(); -             C != CEnd; ++C) { -          MarkDeclarationsReferencedInExpr(*C); -        } +      for (auto *Lambda : Rec.Lambdas) { +        for (auto *C : Lambda->capture_inits()) +          MarkDeclarationsReferencedInExpr(C);        }      }    } @@ -11337,6 +11498,12 @@ void Sema::PopExpressionEvaluationContext() {    // Pop the current expression evaluation context off the stack.    ExprEvalContexts.pop_back(); + +  if (!ExprEvalContexts.empty()) +    ExprEvalContexts.back().NumTypos += NumTypos; +  else +    assert(NumTypos == 0 && "There are outstanding typos after popping the " +                            "last ExpressionEvaluationContextRecord");  }  void Sema::DiscardCleanupsInEvaluationContext() { @@ -11385,7 +11552,8 @@ static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) {  /// \brief Mark a function referenced, and check whether it is odr-used  /// (C++ [basic.def.odr]p2, C99 6.9p3) -void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { +void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, +                                  bool OdrUse) {    assert(Func && "No function?");    Func->setReferenced(); @@ -11484,6 +11652,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {    if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))      ResolveExceptionSpec(Loc, FPT); +  if (!OdrUse) return; +    // Implicit instantiation of function templates and member functions of    // class templates.    if (Func->isImplicitlyInstantiable()) { @@ -11636,7 +11806,7 @@ static DeclContext *getParentOfCapturingContextOrNull(DeclContext *DC, VarDecl *                                   const bool Diagnose, Sema &S) {    if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) || isLambdaCallOperator(DC))      return getLambdaAwareParentOfDeclContext(DC); -  else { +  else if (Var->hasLocalStorage()) {      if (Diagnose)         diagnoseUncapturableValueReference(S, Loc, Var, DC);    } @@ -11665,13 +11835,10 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var,      return false;    } -  // Prohibit variably-modified types; they're difficult to deal with. -  if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) { +  // Prohibit variably-modified types in blocks; they're difficult to deal with. +  if (Var->getType()->isVariablyModifiedType() && IsBlock) {      if (Diagnose) { -      if (IsBlock) -        S.Diag(Loc, diag::err_ref_vm_type); -      else -        S.Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName(); +      S.Diag(Loc, diag::err_ref_vm_type);        S.Diag(Var->getLocation(), diag::note_previous_decl)           << Var->getDeclName();      } @@ -11807,7 +11974,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,                                      const bool BuildAndDiagnose,                                       QualType &CaptureType,                                      QualType &DeclRefType,  -                                    const bool RefersToEnclosingLocal, +                                    const bool RefersToCapturedVariable,                                      Sema &S) {    // By default, capture variables by reference. @@ -11829,7 +11996,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,      Field->setAccess(AS_private);      RD->addDecl(Field); -    CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, +    CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,                                              DeclRefType, VK_LValue, Loc);      Var->setReferenced(true);      Var->markUsed(S.Context); @@ -11837,7 +12004,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,    // Actually capture the variable.    if (BuildAndDiagnose) -    RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToEnclosingLocal, Loc, +    RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToCapturedVariable, Loc,                      SourceLocation(), CaptureType, CopyExpr); @@ -11851,7 +12018,7 @@ static ExprResult addAsFieldToClosureType(Sema &S,                                    VarDecl *Var, QualType FieldType,                                     QualType DeclRefType,                                    SourceLocation Loc, -                                  bool RefersToEnclosingLocal) { +                                  bool RefersToCapturedVariable) {    CXXRecordDecl *Lambda = LSI->Lambda;    // Build the non-static data member. @@ -11880,7 +12047,7 @@ static ExprResult addAsFieldToClosureType(Sema &S,    // C++ [expr.prim.labda]p12:    //   An entity captured by a lambda-expression is odr-used (3.2) in    //   the scope containing the lambda-expression. -  Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,  +  Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,                                             DeclRefType, VK_LValue, Loc);    Var->setReferenced(true);    Var->markUsed(S.Context); @@ -11974,7 +12141,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI,                              const bool BuildAndDiagnose,                               QualType &CaptureType,                              QualType &DeclRefType,  -                            const bool RefersToEnclosingLocal, +                            const bool RefersToCapturedVariable,                              const Sema::TryCaptureKind Kind,                               SourceLocation EllipsisLoc,                              const bool IsTopScope, @@ -12048,7 +12215,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI,    if (BuildAndDiagnose) {      ExprResult Result = addAsFieldToClosureType(S, LSI, Var,                                           CaptureType, DeclRefType, Loc, -                                        RefersToEnclosingLocal); +                                        RefersToCapturedVariable);      if (!Result.isInvalid())        CopyExpr = Result.get();    } @@ -12069,20 +12236,19 @@ static bool captureInLambda(LambdaScopeInfo *LSI,    // Add the capture.    if (BuildAndDiagnose) -    LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToEnclosingLocal,  +    LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToCapturedVariable,                       Loc, EllipsisLoc, CaptureType, CopyExpr);    return true;  } -  bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,                                 TryCaptureKind Kind, SourceLocation EllipsisLoc,                                bool BuildAndDiagnose,                                 QualType &CaptureType,                                QualType &DeclRefType,  						                const unsigned *const FunctionScopeIndexToStopAt) { -  bool Nested = false; +  bool Nested = Var->isInitCapture();    DeclContext *DC = CurContext;    const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt  @@ -12100,8 +12266,13 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,    // If the variable is declared in the current context (and is not an     // init-capture), there is no need to capture it. -  if (!Var->isInitCapture() && Var->getDeclContext() == DC) return true; -  if (!Var->hasLocalStorage()) return true; +  if (!Nested && Var->getDeclContext() == DC) return true; + +  // Capture global variables if it is required to use private copy of this +  // variable. +  bool IsGlobal = !Var->hasLocalStorage(); +  if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var))) +    return true;    // Walk up the stack to determine whether we can capture the variable,    // performing the "simple" checks that don't depend on type. We stop when @@ -12122,8 +12293,17 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,                                                                ExprLoc,                                                                 BuildAndDiagnose,                                                                *this); -    if (!ParentDC) return true; -     +    // We need to check for the parent *first* because, if we *have* +    // private-captured a global variable, we need to recursively capture it in +    // intermediate blocks, lambdas, etc. +    if (!ParentDC) { +      if (IsGlobal) { +        FunctionScopesIndex = MaxFunctionScopesIndex - 1; +        break; +      } +      return true; +    } +      FunctionScopeInfo  *FSI = FunctionScopes[FunctionScopesIndex];      CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI); @@ -12212,14 +12392,37 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,            break;          case Type::VariableArray: {            // Losing element qualification here is fine. -          const VariableArrayType *Vat = cast<VariableArrayType>(Ty); +          const VariableArrayType *VAT = cast<VariableArrayType>(Ty);            // Unknown size indication requires no size computation.            // Otherwise, evaluate and record it. -          if (Expr *Size = Vat->getSizeExpr()) { -            MarkDeclarationsReferencedInExpr(Size); +          if (auto Size = VAT->getSizeExpr()) { +            if (!CSI->isVLATypeCaptured(VAT)) { +              RecordDecl *CapRecord = nullptr; +              if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) { +                CapRecord = LSI->Lambda; +              } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { +                CapRecord = CRSI->TheRecordDecl; +              } +              if (CapRecord) { +                auto ExprLoc = Size->getExprLoc(); +                auto SizeType = Context.getSizeType(); +                // Build the non-static data member. +                auto Field = FieldDecl::Create( +                    Context, CapRecord, ExprLoc, ExprLoc, +                    /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr, +                    /*BW*/ nullptr, /*Mutable*/ false, +                    /*InitStyle*/ ICIS_NoInit); +                Field->setImplicit(true); +                Field->setAccess(AS_private); +                Field->setCapturedVLAType(VAT); +                CapRecord->addDecl(Field); + +                CSI->addVLATypeCapture(ExprLoc, SizeType); +              } +            }            } -          QTy = Vat->getElementType(); +          QTy = VAT->getElementType();            break;          }          case Type::FunctionProto: @@ -12326,6 +12529,14 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,                              DeclRefType, nullptr);  } +bool Sema::NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc) { +  QualType CaptureType; +  QualType DeclRefType; +  return !tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(), +                             /*BuildAndDiagnose=*/false, CaptureType, +                             DeclRefType, nullptr); +} +  QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) {    QualType CaptureType;    QualType DeclRefType; @@ -12388,6 +12599,8 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) {  }  ExprResult Sema::ActOnConstantExpression(ExprResult Res) { +  Res = CorrectDelayedTyposInExpr(Res); +    if (!Res.isUsable())      return Res; @@ -12412,7 +12625,7 @@ void Sema::CleanupVarDeclMarking() {        Var = cast<VarDecl>(ME->getMemberDecl());        Loc = ME->getMemberLoc();      } else { -      llvm_unreachable("Unexpcted expression"); +      llvm_unreachable("Unexpected expression");      }      MarkVarDeclODRUsed(Var, Loc, *this, @@ -12429,6 +12642,9 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,           "Invalid Expr argument to DoMarkVarDeclReferenced");    Var->setReferenced(); +  TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); +  bool MarkODRUsed = true; +    // If the context is not potentially evaluated, this is not an odr-use and    // does not trigger instantiation.    if (!IsPotentiallyEvaluatedContext(SemaRef)) { @@ -12443,25 +12659,29 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,      // arguments, where local variables can't be used.      const bool RefersToEnclosingScope =          (SemaRef.CurContext != Var->getDeclContext() && -         Var->getDeclContext()->isFunctionOrMethod() && -         Var->hasLocalStorage()); -    if (!RefersToEnclosingScope) -      return; - -    if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) { -      // If a variable could potentially be odr-used, defer marking it so -      // until we finish analyzing the full expression for any lvalue-to-rvalue -      // or discarded value conversions that would obviate odr-use. -      // Add it to the list of potential captures that will be analyzed -      // later (ActOnFinishFullExpr) for eventual capture and odr-use marking -      // unless the variable is a reference that was initialized by a constant -      // expression (this will never need to be captured or odr-used). -      assert(E && "Capture variable should be used in an expression."); -      if (!Var->getType()->isReferenceType() || -          !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context)) -        LSI->addPotentialCapture(E->IgnoreParens()); +         Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage()); +    if (RefersToEnclosingScope) { +      if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) { +        // If a variable could potentially be odr-used, defer marking it so +        // until we finish analyzing the full expression for any +        // lvalue-to-rvalue +        // or discarded value conversions that would obviate odr-use. +        // Add it to the list of potential captures that will be analyzed +        // later (ActOnFinishFullExpr) for eventual capture and odr-use marking +        // unless the variable is a reference that was initialized by a constant +        // expression (this will never need to be captured or odr-used). +        assert(E && "Capture variable should be used in an expression."); +        if (!Var->getType()->isReferenceType() || +            !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context)) +          LSI->addPotentialCapture(E->IgnoreParens()); +      }      } -    return; + +    if (!isTemplateInstantiation(TSK)) +    	return; + +    // Instantiate, but do not mark as odr-used, variable templates. +    MarkODRUsed = false;    }    VarTemplateSpecializationDecl *VarSpec = @@ -12473,7 +12693,6 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,    // templates of class templates, and variable template specializations. Delay    // instantiations of variable templates, except for those that could be used    // in a constant expression. -  TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();    if (isTemplateInstantiation(TSK)) {      bool TryInstantiating = TSK == TSK_ImplicitInstantiation; @@ -12513,6 +12732,8 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,      }    } +  if(!MarkODRUsed) return; +    // Per C++11 [basic.def.odr], a variable is odr-used "unless it satisfies    // the requirements for appearing in a constant expression (5.19) and, if    // it is an object, the lvalue-to-rvalue conversion (4.1) @@ -12555,6 +12776,10 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());    if (!MD)      return; +  // Only attempt to devirtualize if this is truly a virtual call. +  bool IsVirtualCall = MD->isVirtual() && !ME->hasQualifier(); +  if (!IsVirtualCall) +    return;    const Expr *Base = ME->getBase();    const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType();    if (!MostDerivedClassDecl) @@ -12602,14 +12827,14 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {  /// normal expression which refers to a variable.  void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {    if (OdrUse) { -    if (VarDecl *VD = dyn_cast<VarDecl>(D)) { +    if (auto *VD = dyn_cast<VarDecl>(D)) {        MarkVariableReferenced(Loc, VD);        return;      } -    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { -      MarkFunctionReferenced(Loc, FD); -      return; -    } +  } +  if (auto *FD = dyn_cast<FunctionDecl>(D)) { +    MarkFunctionReferenced(Loc, FD, OdrUse); +    return;    }    D->setReferenced();  } @@ -12935,6 +13160,7 @@ ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) {          << T << E->getSourceRange();        return ExprError();      } +    CheckBoolLikeConversion(E, Loc);    }    return E; @@ -13306,6 +13532,39 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {          << VD << E->getSourceRange();        return ExprError();      } +    if (const FunctionProtoType *FT = Type->getAs<FunctionProtoType>()) { +      // We must match the FunctionDecl's type to the hack introduced in +      // RebuildUnknownAnyExpr::VisitCallExpr to vararg functions of unknown +      // type. See the lengthy commentary in that routine. +      QualType FDT = FD->getType(); +      const FunctionType *FnType = FDT->castAs<FunctionType>(); +      const FunctionProtoType *Proto = dyn_cast_or_null<FunctionProtoType>(FnType); +      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); +      if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) { +        SourceLocation Loc = FD->getLocation(); +        FunctionDecl *NewFD = FunctionDecl::Create(FD->getASTContext(), +                                      FD->getDeclContext(), +                                      Loc, Loc, FD->getNameInfo().getName(), +                                      DestType, FD->getTypeSourceInfo(), +                                      SC_None, false/*isInlineSpecified*/, +                                      FD->hasPrototype(), +                                      false/*isConstexprSpecified*/); +           +        if (FD->getQualifier()) +          NewFD->setQualifierInfo(FD->getQualifierLoc()); + +        SmallVector<ParmVarDecl*, 16> Params; +        for (const auto &AI : FT->param_types()) { +          ParmVarDecl *Param = +            S.BuildParmVarDeclForTypedef(FD, Loc, AI); +          Param->setScopeInfo(0, Params.size()); +          Params.push_back(Param); +        } +        NewFD->setParams(Params); +        DRE->setDecl(NewFD); +        VD = DRE->getDecl(); +      } +    }      if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))        if (MD->isInstance()) { @@ -13431,6 +13690,15 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {  /// Check for operands with placeholder types and complain if found.  /// Returns true if there was an error and no recovery was possible.  ExprResult Sema::CheckPlaceholderExpr(Expr *E) { +  if (!getLangOpts().CPlusPlus) { +    // C cannot handle TypoExpr nodes on either side of a binop because it +    // doesn't handle dependent types properly, so make sure any TypoExprs have +    // been dealt with before checking the operands. +    ExprResult Result = CorrectDelayedTyposInExpr(E); +    if (!Result.isUsable()) return ExprError(); +    E = Result.get(); +  } +    const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType();    if (!placeholderType) return E; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 0dabdca29553..422398ebeb1e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -13,6 +13,7 @@  //===----------------------------------------------------------------------===//  #include "clang/Sema/SemaInternal.h" +#include "TreeTransform.h"  #include "TypeLocBuilder.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/ASTLambda.h" @@ -67,6 +68,7 @@ ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS,      break;    case NestedNameSpecifier::Global: +  case NestedNameSpecifier::Super:    case NestedNameSpecifier::Namespace:    case NestedNameSpecifier::NamespaceAlias:      llvm_unreachable("Nested name specifier is not a type for inheriting ctor"); @@ -198,6 +200,7 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,      if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {        QualType T = Context.getTypeDeclType(Type); +      MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);        if (SearchType.isNull() || SearchType->isDependentType() ||            Context.hasSameUnqualifiedType(T, SearchType)) { @@ -354,6 +357,7 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,      return true;    case NestedNameSpecifier::Global: +  case NestedNameSpecifier::Super:    case NestedNameSpecifier::Namespace:    case NestedNameSpecifier::NamespaceAlias:      return false; @@ -380,6 +384,9 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,        RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))      return ExprError(); +  if (T->isVariablyModifiedType()) +    return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T); +    return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,                                       SourceRange(TypeidLoc, RParenLoc));  } @@ -389,6 +396,7 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,                                  SourceLocation TypeidLoc,                                  Expr *E,                                  SourceLocation RParenLoc) { +  bool WasEvaluated = false;    if (E && !E->isTypeDependent()) {      if (E->getType()->isPlaceholderType()) {        ExprResult result = CheckPlaceholderExpr(E); @@ -418,6 +426,7 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,          // We require a vtable to query the type at run time.          MarkVTableUsed(TypeidLoc, RecordD); +        WasEvaluated = true;        }      } @@ -434,6 +443,18 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,      }    } +  if (E->getType()->isVariablyModifiedType()) +    return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) +                     << E->getType()); +  else if (ActiveTemplateInstantiations.empty() && +           E->HasSideEffects(Context, WasEvaluated)) { +    // The expression operand for typeid is in an unevaluated expression +    // context, so side effects could result in unintended consequences. +    Diag(E->getExprLoc(), WasEvaluated +                              ? diag::warn_side_effects_typeid +                              : diag::warn_side_effects_unevaluated_context); +  } +    return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,                                       SourceRange(TypeidLoc, RParenLoc));  } @@ -580,15 +601,15 @@ Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {    bool IsThrownVarInScope = false;    if (Ex) {      // C++0x [class.copymove]p31: -    //   When certain criteria are met, an implementation is allowed to omit the  +    //   When certain criteria are met, an implementation is allowed to omit the      //   copy/move construction of a class object [...]      // -    //     - in a throw-expression, when the operand is the name of a  +    //     - in a throw-expression, when the operand is the name of a      //       non-volatile automatic object (other than a function or catch- -    //       clause parameter) whose scope does not extend beyond the end of the  -    //       innermost enclosing try-block (if there is one), the copy/move  -    //       operation from the operand to the exception object (15.1) can be  -    //       omitted by constructing the automatic object directly into the  +    //       clause parameter) whose scope does not extend beyond the end of the +    //       innermost enclosing try-block (if there is one), the copy/move +    //       operation from the operand to the exception object (15.1) can be +    //       omitted by constructing the automatic object directly into the      //       exception object      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens()))        if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) { @@ -1083,7 +1104,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,        DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;        if (Expr *NumElts = (Expr *)Array.NumElts) {          if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) { -          if (getLangOpts().CPlusPlus1y) { +          if (getLangOpts().CPlusPlus14) {  	    // C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator  	    //   shall be a converted constant expression (5.19) of type std::size_t  	    //   and shall evaluate to a strictly positive value. @@ -1257,7 +1278,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,    //   std::size_t.    if (ArraySize && !ArraySize->isTypeDependent()) {      ExprResult ConvertedSize; -    if (getLangOpts().CPlusPlus1y) { +    if (getLangOpts().CPlusPlus14) {        assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");        ConvertedSize = PerformImplicitConversion(ArraySize, Context.getSizeType(), @@ -2072,19 +2093,18 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,      if (!getLangOpts().CPlusPlus11) {        BadAllocType = Context.getTypeDeclType(getStdBadAlloc());        assert(StdBadAlloc && "Must have std::bad_alloc declared"); -      EPI.ExceptionSpecType = EST_Dynamic; -      EPI.NumExceptions = 1; -      EPI.Exceptions = &BadAllocType; +      EPI.ExceptionSpec.Type = EST_Dynamic; +      EPI.ExceptionSpec.Exceptions = llvm::makeArrayRef(BadAllocType);      }    } else { -    EPI.ExceptionSpecType = getLangOpts().CPlusPlus11 ? -                                EST_BasicNoexcept : EST_DynamicNone; +    EPI.ExceptionSpec = +        getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone;    }    QualType Params[] = { Param1, Param2 };    QualType FnType = Context.getFunctionType( -      Return, ArrayRef<QualType>(Params, NumParams), EPI); +      Return, llvm::makeArrayRef(Params, NumParams), EPI);    FunctionDecl *Alloc =      FunctionDecl::Create(Context, GlobalCtx, SourceLocation(),                           SourceLocation(), Name, @@ -2102,7 +2122,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,                                          SC_None, nullptr);      ParamDecls[I]->setImplicit();    } -  Alloc->setParams(ArrayRef<ParmVarDecl*>(ParamDecls, NumParams)); +  Alloc->setParams(llvm::makeArrayRef(ParamDecls, NumParams));    Context.getTranslationUnitDecl()->addDecl(Alloc);    IdResolver.tryAddTopLevelDecl(Alloc, Name); @@ -2622,8 +2642,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,          // Do no conversion if dealing with ... for the first conversion.          if (!ICS.UserDefined.EllipsisConversion) {            // If the user-defined conversion is specified by a constructor, the -          // initial standard conversion sequence converts the source type to the -          // type required by the argument of the constructor +          // initial standard conversion sequence converts the source type to +          // the type required by the argument of the constructor            BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType();          }        } @@ -2739,15 +2759,19 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,    // Perform the first implicit conversion.    switch (SCS.First) {    case ICK_Identity: -    // Nothing to do. +    if (const AtomicType *FromAtomic = FromType->getAs<AtomicType>()) { +      FromType = FromAtomic->getValueType().getUnqualifiedType(); +      From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic, +                                      From, /*BasePath=*/nullptr, VK_RValue); +    }      break;    case ICK_Lvalue_To_Rvalue: {      assert(From->getObjectKind() != OK_ObjCProperty); -    FromType = FromType.getUnqualifiedType();      ExprResult FromRes = DefaultLvalueConversion(From);      assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!");      From = FromRes.get(); +    FromType = From->getType();      break;    } @@ -2770,10 +2794,29 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,    // Perform the second implicit conversion    switch (SCS.Second) {    case ICK_Identity: -    // If both sides are functions (or pointers/references to them), there could -    // be incompatible exception declarations. -    if (CheckExceptionSpecCompatibility(From, ToType)) -      return ExprError(); +    // C++ [except.spec]p5: +    //   [For] assignment to and initialization of pointers to functions, +    //   pointers to member functions, and references to functions: the +    //   target entity shall allow at least the exceptions allowed by the +    //   source value in the assignment or initialization. +    switch (Action) { +    case AA_Assigning: +    case AA_Initializing: +      // Note, function argument passing and returning are initialization. +    case AA_Passing: +    case AA_Returning: +    case AA_Sending: +    case AA_Passing_CFAudited: +      if (CheckExceptionSpecCompatibility(From, ToType)) +        return ExprError(); +      break; + +    case AA_Casting: +    case AA_Converting: +      // Casts and implicit conversions are not initialization, so are not +      // checked for exception specification mismatches. +      break; +    }      // Nothing else to do.      break; @@ -2899,6 +2942,14 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,        return ExprError();      if (CheckExceptionSpecCompatibility(From, ToType))        return ExprError(); + +    // We may not have been able to figure out what this member pointer resolved +    // to up until this exact point.  Attempt to lock-in it's inheritance model. +    QualType FromType = From->getType(); +    if (FromType->isMemberPointerType()) +      if (Context.getTargetInfo().getCXXABI().isMicrosoft()) +        RequireCompleteType(From->getExprLoc(), FromType, 0); +      From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)               .get();      break; @@ -3642,12 +3693,13 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,        if (T->isObjectType() || T->isFunctionType())          T = S.Context.getRValueReferenceType(T);        OpaqueArgExprs.push_back( -        OpaqueValueExpr(Args[I]->getTypeLoc().getLocStart(),  +        OpaqueValueExpr(Args[I]->getTypeLoc().getLocStart(),                          T.getNonLValueExprType(S.Context),                          Expr::getValueKindForType(T))); -      ArgExprs.push_back(&OpaqueArgExprs.back());      } -     +    for (Expr &E : OpaqueArgExprs) +      ArgExprs.push_back(&E); +      // Perform the initialization in an unevaluated context within a SFINAE       // trap at translation unit scope.      EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated); @@ -4549,10 +4601,14 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,    //      the usual arithmetic conversions are performed to bring them to a    //      common type, and the result is of that type.    if (LTy->isArithmeticType() && RTy->isArithmeticType()) { -    UsualArithmeticConversions(LHS, RHS); +    QualType ResTy = UsualArithmeticConversions(LHS, RHS);      if (LHS.isInvalid() || RHS.isInvalid())        return QualType(); -    return LHS.get()->getType(); + +    LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); +    RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy)); + +    return ResTy;    }    //   -- The second and third operands have pointer type, or one has pointer @@ -4993,9 +5049,8 @@ Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {    if (!ExprNeedsCleanups)      return SubExpr; -  ArrayRef<ExprWithCleanups::CleanupObject> Cleanups -    = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup, -                         ExprCleanupObjects.size() - FirstCleanup); +  auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup, +                                     ExprCleanupObjects.size() - FirstCleanup);    Expr *E = ExprWithCleanups::Create(Context, SubExpr, Cleanups);    DiscardCleanupsInEvaluationContext(); @@ -5231,7 +5286,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,          OperatorArrows.push_back(OpCall->getDirectCallee());        BaseType = Base->getType();        CanQualType CBaseType = Context.getCanonicalType(BaseType); -      if (!CTypes.insert(CBaseType)) { +      if (!CTypes.insert(CBaseType).second) {          Diag(OpLoc, diag::err_operator_arrow_circular) << StartingType;          noteOperatorArrows(*this, OperatorArrows);          return ExprError(); @@ -5581,7 +5636,8 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,    if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))      return ExprError(); -  QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); +  QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc(), +                                 false);    TypeLocBuilder TLB;    DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); @@ -5649,6 +5705,13 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,  ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,                                        SourceLocation RParen) { +  if (ActiveTemplateInstantiations.empty() && +      Operand->HasSideEffects(Context, false)) { +    // The expression operand for noexcept is in an unevaluated expression +    // context, so side effects could result in unintended consequences. +    Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context); +  } +    CanThrowResult CanThrow = canThrow(Operand);    return new (Context)        CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen); @@ -5905,6 +5968,284 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(    CurrentLSI->clearPotentialCaptures();  } +static ExprResult attemptRecovery(Sema &SemaRef, +                                  const TypoCorrectionConsumer &Consumer, +                                  TypoCorrection TC) { +  LookupResult R(SemaRef, Consumer.getLookupResult().getLookupNameInfo(), +                 Consumer.getLookupResult().getLookupKind()); +  const CXXScopeSpec *SS = Consumer.getSS(); +  CXXScopeSpec NewSS; + +  // Use an approprate CXXScopeSpec for building the expr. +  if (auto *NNS = TC.getCorrectionSpecifier()) +    NewSS.MakeTrivial(SemaRef.Context, NNS, TC.getCorrectionRange()); +  else if (SS && !TC.WillReplaceSpecifier()) +    NewSS = *SS; + +  if (auto *ND = TC.getCorrectionDecl()) { +    R.setLookupName(ND->getDeclName()); +    R.addDecl(ND); +    if (ND->isCXXClassMember()) { +      // Figure out the correct naming class to add to the LookupResult. +      CXXRecordDecl *Record = nullptr; +      if (auto *NNS = TC.getCorrectionSpecifier()) +        Record = NNS->getAsType()->getAsCXXRecordDecl(); +      if (!Record) +        Record = +            dyn_cast<CXXRecordDecl>(ND->getDeclContext()->getRedeclContext()); +      if (Record) +        R.setNamingClass(Record); + +      // Detect and handle the case where the decl might be an implicit +      // member. +      bool MightBeImplicitMember; +      if (!Consumer.isAddressOfOperand()) +        MightBeImplicitMember = true; +      else if (!NewSS.isEmpty()) +        MightBeImplicitMember = false; +      else if (R.isOverloadedResult()) +        MightBeImplicitMember = false; +      else if (R.isUnresolvableResult()) +        MightBeImplicitMember = true; +      else +        MightBeImplicitMember = isa<FieldDecl>(ND) || +                                isa<IndirectFieldDecl>(ND) || +                                isa<MSPropertyDecl>(ND); + +      if (MightBeImplicitMember) +        return SemaRef.BuildPossibleImplicitMemberExpr( +            NewSS, /*TemplateKWLoc*/ SourceLocation(), R, +            /*TemplateArgs*/ nullptr); +    } else if (auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) { +      return SemaRef.LookupInObjCMethod(R, Consumer.getScope(), +                                        Ivar->getIdentifier()); +    } +  } + +  return SemaRef.BuildDeclarationNameExpr(NewSS, R, /*NeedsADL*/ false, +                                          /*AcceptInvalidDecl*/ true); +} + +namespace { +class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> { +  llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs; + +public: +  explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs) +      : TypoExprs(TypoExprs) {} +  bool VisitTypoExpr(TypoExpr *TE) { +    TypoExprs.insert(TE); +    return true; +  } +}; + +class TransformTypos : public TreeTransform<TransformTypos> { +  typedef TreeTransform<TransformTypos> BaseTransform; + +  llvm::function_ref<ExprResult(Expr *)> ExprFilter; +  llvm::SmallSetVector<TypoExpr *, 2> TypoExprs, AmbiguousTypoExprs; +  llvm::SmallDenseMap<TypoExpr *, ExprResult, 2> TransformCache; +  llvm::SmallDenseMap<OverloadExpr *, Expr *, 4> OverloadResolution; + +  /// \brief Emit diagnostics for all of the TypoExprs encountered. +  /// If the TypoExprs were successfully corrected, then the diagnostics should +  /// suggest the corrections. Otherwise the diagnostics will not suggest +  /// anything (having been passed an empty TypoCorrection). +  void EmitAllDiagnostics() { +    for (auto E : TypoExprs) { +      TypoExpr *TE = cast<TypoExpr>(E); +      auto &State = SemaRef.getTypoExprState(TE); +      if (State.DiagHandler) { +        TypoCorrection TC = State.Consumer->getCurrentCorrection(); +        ExprResult Replacement = TransformCache[TE]; + +        // Extract the NamedDecl from the transformed TypoExpr and add it to the +        // TypoCorrection, replacing the existing decls. This ensures the right +        // NamedDecl is used in diagnostics e.g. in the case where overload +        // resolution was used to select one from several possible decls that +        // had been stored in the TypoCorrection. +        if (auto *ND = getDeclFromExpr( +                Replacement.isInvalid() ? nullptr : Replacement.get())) +          TC.setCorrectionDecl(ND); + +        State.DiagHandler(TC); +      } +      SemaRef.clearDelayedTypo(TE); +    } +  } + +  /// \brief If corrections for the first TypoExpr have been exhausted for a +  /// given combination of the other TypoExprs, retry those corrections against +  /// the next combination of substitutions for the other TypoExprs by advancing +  /// to the next potential correction of the second TypoExpr. For the second +  /// and subsequent TypoExprs, if its stream of corrections has been exhausted, +  /// the stream is reset and the next TypoExpr's stream is advanced by one (a +  /// TypoExpr's correction stream is advanced by removing the TypoExpr from the +  /// TransformCache). Returns true if there is still any untried combinations +  /// of corrections. +  bool CheckAndAdvanceTypoExprCorrectionStreams() { +    for (auto TE : TypoExprs) { +      auto &State = SemaRef.getTypoExprState(TE); +      TransformCache.erase(TE); +      if (!State.Consumer->finished()) +        return true; +      State.Consumer->resetCorrectionStream(); +    } +    return false; +  } + +  NamedDecl *getDeclFromExpr(Expr *E) { +    if (auto *OE = dyn_cast_or_null<OverloadExpr>(E)) +      E = OverloadResolution[OE]; + +    if (!E) +      return nullptr; +    if (auto *DRE = dyn_cast<DeclRefExpr>(E)) +      return DRE->getDecl(); +    if (auto *ME = dyn_cast<MemberExpr>(E)) +      return ME->getMemberDecl(); +    // FIXME: Add any other expr types that could be be seen by the delayed typo +    // correction TreeTransform for which the corresponding TypoCorrection could +    // contain multiple decls. +    return nullptr; +  } + +  ExprResult TryTransform(Expr *E) { +    Sema::SFINAETrap Trap(SemaRef); +    ExprResult Res = TransformExpr(E); +    if (Trap.hasErrorOccurred() || Res.isInvalid()) +      return ExprError(); + +    return ExprFilter(Res.get()); +  } + +public: +  TransformTypos(Sema &SemaRef, llvm::function_ref<ExprResult(Expr *)> Filter) +      : BaseTransform(SemaRef), ExprFilter(Filter) {} + +  ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, +                                   MultiExprArg Args, +                                   SourceLocation RParenLoc, +                                   Expr *ExecConfig = nullptr) { +    auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args, +                                                 RParenLoc, ExecConfig); +    if (auto *OE = dyn_cast<OverloadExpr>(Callee)) { +      if (Result.isUsable()) { +        Expr *ResultCall = Result.get(); +        if (auto *BE = dyn_cast<CXXBindTemporaryExpr>(ResultCall)) +          ResultCall = BE->getSubExpr(); +        if (auto *CE = dyn_cast<CallExpr>(ResultCall)) +          OverloadResolution[OE] = CE->getCallee(); +      } +    } +    return Result; +  } + +  ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); } + +  ExprResult TransformOpaqueValueExpr(OpaqueValueExpr *E) { +    if (Expr *SE = E->getSourceExpr()) +      return TransformExpr(SE); +    return BaseTransform::TransformOpaqueValueExpr(E); +  } + +  ExprResult Transform(Expr *E) { +    ExprResult Res; +    while (true) { +      Res = TryTransform(E); + +      // Exit if either the transform was valid or if there were no TypoExprs +      // to transform that still have any untried correction candidates.. +      if (!Res.isInvalid() || +          !CheckAndAdvanceTypoExprCorrectionStreams()) +        break; +    } + +    // Ensure none of the TypoExprs have multiple typo correction candidates +    // with the same edit length that pass all the checks and filters. +    // TODO: Properly handle various permutations of possible corrections when +    // there is more than one potentially ambiguous typo correction. +    while (!AmbiguousTypoExprs.empty()) { +      auto TE  = AmbiguousTypoExprs.back(); +      auto Cached = TransformCache[TE]; +      AmbiguousTypoExprs.pop_back(); +      TransformCache.erase(TE); +      if (!TryTransform(E).isInvalid()) { +        SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream(); +        TransformCache.erase(TE); +        Res = ExprError(); +        break; +      } else +        TransformCache[TE] = Cached; +    } + +    // Ensure that all of the TypoExprs within the current Expr have been found. +    if (!Res.isUsable()) +      FindTypoExprs(TypoExprs).TraverseStmt(E); + +    EmitAllDiagnostics(); + +    return Res; +  } + +  ExprResult TransformTypoExpr(TypoExpr *E) { +    // If the TypoExpr hasn't been seen before, record it. Otherwise, return the +    // cached transformation result if there is one and the TypoExpr isn't the +    // first one that was encountered. +    auto &CacheEntry = TransformCache[E]; +    if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) { +      return CacheEntry; +    } + +    auto &State = SemaRef.getTypoExprState(E); +    assert(State.Consumer && "Cannot transform a cleared TypoExpr"); + +    // For the first TypoExpr and an uncached TypoExpr, find the next likely +    // typo correction and return it. +    while (TypoCorrection TC = State.Consumer->getNextCorrection()) { +      ExprResult NE = State.RecoveryHandler ? +          State.RecoveryHandler(SemaRef, E, TC) : +          attemptRecovery(SemaRef, *State.Consumer, TC); +      if (!NE.isInvalid()) { +        // Check whether there may be a second viable correction with the same +        // edit distance; if so, remember this TypoExpr may have an ambiguous +        // correction so it can be more thoroughly vetted later. +        TypoCorrection Next; +        if ((Next = State.Consumer->peekNextCorrection()) && +            Next.getEditDistance(false) == TC.getEditDistance(false)) { +          AmbiguousTypoExprs.insert(E); +        } else { +          AmbiguousTypoExprs.remove(E); +        } +        assert(!NE.isUnset() && +               "Typo was transformed into a valid-but-null ExprResult"); +        return CacheEntry = NE; +      } +    } +    return CacheEntry = ExprError(); +  } +}; +} + +ExprResult Sema::CorrectDelayedTyposInExpr( +    Expr *E, llvm::function_ref<ExprResult(Expr *)> Filter) { +  // If the current evaluation context indicates there are uncorrected typos +  // and the current expression isn't guaranteed to not have typos, try to +  // resolve any TypoExpr nodes that might be in the expression. +  if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos && +      (E->isTypeDependent() || E->isValueDependent() || +       E->isInstantiationDependent())) { +    auto TyposResolved = DelayedTypos.size(); +    auto Result = TransformTypos(*this, Filter).Transform(E); +    TyposResolved -= DelayedTypos.size(); +    if (Result.isInvalid() || Result.get() != E) { +      ExprEvalContexts.back().NumTypos -= TyposResolved; +      return Result; +    } +    assert(TyposResolved == 0 && "Corrected typo but got same Expr back?"); +  } +  return E; +}  ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,                                       bool DiscardedValue, @@ -5952,6 +6293,10 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,        return ExprError();    } +  FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); +  if (FullExpr.isInvalid()) +    return ExprError(); +    CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr);    // At the end of this full expression (which could be a deeply nested  diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index ef7898208cae..af1cf9046113 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -10,7 +10,7 @@  //  This file implements semantic analysis member access expressions.  //  //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaInternal.h" +#include "clang/Sema/Overload.h"  #include "clang/AST/ASTLambda.h"  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclObjC.h" @@ -21,6 +21,7 @@  #include "clang/Sema/Lookup.h"  #include "clang/Sema/Scope.h"  #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaInternal.h"  using namespace clang;  using namespace sema; @@ -89,7 +90,6 @@ enum IMAKind {  /// conservatively answer "yes", in which case some errors will simply  /// not be caught until template-instantiation.  static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, -                                            Scope *CurScope,                                              const LookupResult &R) {    assert(!R.empty() && (*R.begin())->isCXXClassMember()); @@ -204,6 +204,9 @@ static void diagnoseInstanceReference(Sema &SemaRef,    SourceRange Range(Loc);    if (SS.isSet()) Range.setBegin(SS.getRange().getBegin()); +  // Look through using shadow decls and aliases. +  Rep = Rep->getUnderlyingDecl(); +    DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext();    CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC);    CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr; @@ -236,7 +239,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,                                        SourceLocation TemplateKWLoc,                                        LookupResult &R,                                  const TemplateArgumentListInfo *TemplateArgs) { -  switch (ClassifyImplicitMemberAccess(*this, CurScope, R)) { +  switch (ClassifyImplicitMemberAccess(*this, R)) {    case IMA_Instance:      return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true); @@ -536,9 +539,17 @@ namespace {  // FunctionTemplateDecl and are declared in the current record or, for a C++  // classes, one of its base classes.  class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback { - public: +public:    explicit RecordMemberExprValidatorCCC(const RecordType *RTy) -      : Record(RTy->getDecl()) {} +      : Record(RTy->getDecl()) { +    // Don't add bare keywords to the consumer since they will always fail +    // validation by virtue of not being associated with any decls. +    WantTypeSpecifiers = false; +    WantExpressionKeywords = false; +    WantCXXNamedCasts = false; +    WantFunctionLikeCasts = false; +    WantRemainingKeywords = false; +  }    bool ValidateCandidate(const TypoCorrection &candidate) override {      NamedDecl *ND = candidate.getCorrectionDecl(); @@ -554,8 +565,8 @@ class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {      if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) {        // Accept candidates that occur in any of the current class' base classes.        for (const auto &BS : RD->bases()) { -        if (const RecordType *BSTy = dyn_cast_or_null<RecordType>( -                BS.getType().getTypePtrOrNull())) { +        if (const RecordType *BSTy = +                dyn_cast_or_null<RecordType>(BS.getType().getTypePtrOrNull())) {            if (BSTy->getDecl()->containsDecl(ND))              return true;          } @@ -565,17 +576,19 @@ class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {      return false;    } - private: +private:    const RecordDecl *const Record;  };  } -static bool -LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,  -                         SourceRange BaseRange, const RecordType *RTy, -                         SourceLocation OpLoc, CXXScopeSpec &SS, -                         bool HasTemplateArgs) { +static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, +                                     Expr *BaseExpr, +                                     const RecordType *RTy, +                                     SourceLocation OpLoc, bool IsArrow, +                                     CXXScopeSpec &SS, bool HasTemplateArgs, +                                     TypoExpr *&TE) { +  SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();    RecordDecl *RDecl = RTy->getDecl();    if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) &&        SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0), @@ -600,7 +613,7 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,      if (SemaRef.RequireCompleteDeclContext(SS, DC)) {        SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag) -        << SS.getRange() << DC; +          << SS.getRange() << DC;        return true;      } @@ -608,47 +621,48 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,      if (!isa<TypeDecl>(DC)) {        SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_nonclass) -        << DC << SS.getRange(); +          << DC << SS.getRange();        return true;      }    }    // The record definition is complete, now look up the member. -  SemaRef.LookupQualifiedName(R, DC); +  SemaRef.LookupQualifiedName(R, DC, SS);    if (!R.empty())      return false; -  // We didn't find anything with the given name, so try to correct -  // for typos. -  DeclarationName Name = R.getLookupName(); -  RecordMemberExprValidatorCCC Validator(RTy); -  TypoCorrection Corrected = SemaRef.CorrectTypo(R.getLookupNameInfo(), -                                                 R.getLookupKind(), nullptr, -                                                 &SS, Validator, -                                                 Sema::CTK_ErrorRecovery, DC); -  R.clear(); -  if (Corrected.isResolved() && !Corrected.isKeyword()) { -    R.setLookupName(Corrected.getCorrection()); -    for (TypoCorrection::decl_iterator DI = Corrected.begin(), -                                       DIEnd = Corrected.end(); -         DI != DIEnd; ++DI) { -      R.addDecl(*DI); -    } -    R.resolveKind(); - -    // If we're typo-correcting to an overloaded name, we don't yet have enough -    // information to do overload resolution, so we don't know which previous -    // declaration to point to. -    if (Corrected.isOverloaded()) -      Corrected.setCorrectionDecl(nullptr); -    bool DroppedSpecifier = -        Corrected.WillReplaceSpecifier() && -        Name.getAsString() == Corrected.getAsString(SemaRef.getLangOpts()); -    SemaRef.diagnoseTypo(Corrected, -                         SemaRef.PDiag(diag::err_no_member_suggest) -                           << Name << DC << DroppedSpecifier << SS.getRange()); -  } +  DeclarationName Typo = R.getLookupName(); +  SourceLocation TypoLoc = R.getNameLoc(); +  TE = SemaRef.CorrectTypoDelayed( +      R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, +      llvm::make_unique<RecordMemberExprValidatorCCC>(RTy), +      [=, &SemaRef](const TypoCorrection &TC) { +        if (TC) { +          assert(!TC.isKeyword() && +                 "Got a keyword as a correction for a member!"); +          bool DroppedSpecifier = +              TC.WillReplaceSpecifier() && +              Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts()); +          SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) +                                       << Typo << DC << DroppedSpecifier +                                       << SS.getRange()); +        } else { +          SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC << BaseRange; +        } +      }, +      [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable { +        R.clear(); // Ensure there's no decls lingering in the shared state. +        R.suppressDiagnostics(); +        R.setLookupName(TC.getCorrection()); +        for (NamedDecl *ND : TC) +          R.addDecl(ND); +        R.resolveKind(); +        return SemaRef.BuildMemberReferenceExpr( +            BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(), +            nullptr, R, nullptr); +      }, +      Sema::CTK_ErrorRecovery, DC);    return false;  } @@ -678,12 +692,15 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,    // Implicit member accesses.    if (!Base) { +    TypoExpr *TE = nullptr;      QualType RecordTy = BaseType;      if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType(); -    if (LookupMemberExprInRecord(*this, R, SourceRange(), -                                 RecordTy->getAs<RecordType>(), -                                 OpLoc, SS, TemplateArgs != nullptr)) +    if (LookupMemberExprInRecord(*this, R, nullptr, +                                 RecordTy->getAs<RecordType>(), OpLoc, IsArrow, +                                 SS, TemplateArgs != nullptr, TE))        return ExprError(); +    if (TE) +      return TE;    // Explicit member accesses.    } else { @@ -1211,13 +1228,16 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,    // Handle field access to simple records.    if (const RecordType *RTy = BaseType->getAs<RecordType>()) { -    if (LookupMemberExprInRecord(S, R, BaseExpr.get()->getSourceRange(), -                                 RTy, OpLoc, SS, HasTemplateArgs)) +    TypoExpr *TE = nullptr; +    if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, +                                 OpLoc, IsArrow, SS, HasTemplateArgs, TE))        return ExprError();      // Returning valid-but-null is how we indicate to the caller that -    // the lookup result was filled in. -    return ExprResult((Expr *)nullptr); +    // the lookup result was filled in. If typo correction was attempted and +    // failed, the lookup result will have been cleared--that combined with the +    // valid-but-null ExprResult will trigger the appropriate diagnostics. +    return ExprResult(TE);    }    // Handle ivar access to Objective-C objects. @@ -1262,11 +1282,11 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,      if (!IV) {        // Attempt to correct for typos in ivar names. -      DeclFilterCCC<ObjCIvarDecl> Validator; -      Validator.IsObjCIvarLookup = IsArrow; +      auto Validator = llvm::make_unique<DeclFilterCCC<ObjCIvarDecl>>(); +      Validator->IsObjCIvarLookup = IsArrow;        if (TypoCorrection Corrected = S.CorrectTypo(                R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr, -              Validator, Sema::CTK_ErrorRecovery, IDecl)) { +              std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) {          IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();          S.diagnoseTypo(              Corrected, diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 500233203c79..9c3b51c623d3 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -944,7 +944,11 @@ ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,          return ExprError();      std::string Str; -    Context.getObjCEncodingForType(EncodedType, Str); +    QualType NotEncodedT; +    Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT); +    if (!NotEncodedT.isNull()) +      Diag(AtLoc, diag::warn_incomplete_encoded_type) +        << EncodedType << NotEncodedT;      // The type of @encode is the same as the type of the corresponding string,      // which is an array type. @@ -983,7 +987,7 @@ static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,    ObjCMethodList *M = &MethList;    bool Warned = false;    for (M = M->getNext(); M; M=M->getNext()) { -    ObjCMethodDecl *MatchingMethodDecl = M->Method; +    ObjCMethodDecl *MatchingMethodDecl = M->getMethod();      if (MatchingMethodDecl == Method ||          isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||          MatchingMethodDecl->getSelector() != Method->getSelector()) @@ -1086,6 +1090,7 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,      case OMF_mutableCopy:      case OMF_new:      case OMF_self: +    case OMF_initialize:      case OMF_performSelector:        break;      } @@ -1105,6 +1110,8 @@ ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,      Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;      return true;    } +  if (PDecl->hasDefinition()) +    PDecl = PDecl->getDefinition();    QualType Ty = Context.getObjCProtoType();    if (Ty.isNull()) @@ -1222,12 +1229,8 @@ void Sema::EmitRelatedResultTypeNoteForReturn(QualType destType) {    // 'instancetype'.    if (const ObjCMethodDecl *overridden =          findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) { -    SourceLocation loc; -    SourceRange range; -    if (TypeSourceInfo *TSI = overridden->getReturnTypeSourceInfo()) { -      range = TSI->getTypeLoc().getSourceRange(); -      loc = range.getBegin(); -    } +    SourceRange range = overridden->getReturnTypeSourceRange(); +    SourceLocation loc = range.getBegin();      if (loc.isInvalid())        loc = overridden->getLocation();      Diag(loc, diag::note_related_result_type_explicit) @@ -1276,6 +1279,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,                                       ObjCMethodDecl *Method,                                       bool isClassMessage, bool isSuperMessage,                                       SourceLocation lbrac, SourceLocation rbrac, +                                     SourceRange RecRange,                                       QualType &ReturnType, ExprValueKind &VK) {    SourceLocation SelLoc;    if (!SelectorLocs.empty() && SelectorLocs.front().isValid()) @@ -1317,9 +1321,12 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,                                    : diag::warn_instance_method_not_found_with_typo;          Selector MatchedSel = OMD->getSelector();          SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back()); -        Diag(SelLoc, DiagID) -          << Sel<< isClassMessage << MatchedSel -          << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString()); +        if (MatchedSel.isUnarySelector()) +          Diag(SelLoc, DiagID) +            << Sel<< isClassMessage << MatchedSel +            << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString()); +        else +          Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;        }        else          Diag(SelLoc, DiagID) @@ -1327,9 +1334,15 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,                                                  SelectorLocs.back());        // Find the class to which we are sending this message.        if (ReceiverType->isObjCObjectPointerType()) { -        if (ObjCInterfaceDecl *Class = -              ReceiverType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()) -          Diag(Class->getLocation(), diag::note_receiver_class_declared); +        if (ObjCInterfaceDecl *ThisClass = +            ReceiverType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()) { +          Diag(ThisClass->getLocation(), diag::note_receiver_class_declared); +          if (!RecRange.isInvalid()) +            if (ThisClass->lookupClassMethod(Sel)) +              Diag(RecRange.getBegin(),diag::note_receiver_expr_here) +                << FixItHint::CreateReplacement(RecRange, +                                                ThisClass->getNameAsString()); +        }        }      } @@ -1400,7 +1413,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,      InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,                                                                        param); -    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, argExpr); +    ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), argExpr);      if (ArgE.isInvalid())        IsError = true;      else @@ -1434,7 +1447,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,    // Do additional checkings on method.    IsError |= CheckObjCMethodCall( -      Method, SelLoc, makeArrayRef<const Expr *>(Args.data(), Args.size())); +      Method, SelLoc, makeArrayRef(Args.data(), Args.size()));    return IsError;  } @@ -1651,6 +1664,22 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,    if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))      return ExprError(); +  // Special warning if member name used in a property-dot for a setter accessor +  // does not use a property with same name; e.g. obj.X = ... for a property with +  // name 'x'. +  if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() +      && !IFace->FindPropertyDeclaration(Member)) { +      if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) { +        // Do not warn if user is using property-dot syntax to make call to +        // user named setter. +        if (!(PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter)) +          Diag(MemberLoc, +               diag::warn_property_access_suggest) +          << MemberName << QualType(OPT, 0) << PDecl->getName() +          << FixItHint::CreateReplacement(MemberLoc, PDecl->getName()); +      } +  } +    if (Getter || Setter) {      if (Super)        return new (Context) @@ -1664,10 +1693,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,    }    // Attempt to correct for typos in property names. -  DeclFilterCCC<ObjCPropertyDecl> Validator; -  if (TypoCorrection Corrected = CorrectTypo( -          DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, -          nullptr, nullptr, Validator, CTK_ErrorRecovery, IFace, false, OPT)) { +  if (TypoCorrection Corrected = +          CorrectTypo(DeclarationNameInfo(MemberName, MemberLoc), +                      LookupOrdinaryName, nullptr, nullptr, +                      llvm::make_unique<DeclFilterCCC<ObjCPropertyDecl>>(), +                      CTK_ErrorRecovery, IFace, false, OPT)) {      diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest)                                << MemberName << QualType(OPT, 0));      DeclarationName TypoResult = Corrected.getCorrection(); @@ -1892,11 +1922,10 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,    }    } -  ObjCInterfaceOrSuperCCC Validator(getCurMethodDecl()); -  if (TypoCorrection Corrected = -          CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S, -                      nullptr, Validator, CTK_ErrorRecovery, nullptr, false, -                      nullptr, false)) { +  if (TypoCorrection Corrected = CorrectTypo( +          Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, +          llvm::make_unique<ObjCInterfaceOrSuperCCC>(getCurMethodDecl()), +          CTK_ErrorRecovery, nullptr, false, nullptr, false)) {      if (Corrected.isKeyword()) {        // If we've found the keyword "super" (the only keyword that would be        // returned by CorrectTypo), this is a send to super. @@ -2034,6 +2063,45 @@ static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {                       edit::rewriteObjCRedundantCallWithLiteral);  } +/// \brief Diagnose use of %s directive in an NSString which is being passed +/// as formatting string to formatting method. +static void +DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, +                                        ObjCMethodDecl *Method, +                                        Selector Sel, +                                        Expr **Args, unsigned NumArgs) { +  unsigned Idx = 0; +  bool Format = false; +  ObjCStringFormatFamily SFFamily = Sel.getStringFormatFamily(); +  if (SFFamily == ObjCStringFormatFamily::SFF_NSString) { +    Idx = 0; +    Format = true; +  } +  else if (Method) { +    for (const auto *I : Method->specific_attrs<FormatAttr>()) { +      if (S.GetFormatNSStringIdx(I, Idx)) { +        Format = true; +        break; +      } +    } +  } +  if (!Format || NumArgs <= Idx) +    return; +   +  Expr *FormatExpr = Args[Idx]; +  if (ObjCStringLiteral *OSL = +      dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) { +    StringLiteral *FormatString = OSL->getString(); +    if (S.FormatStringHasSArg(FormatString)) { +      S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string) +        << "%s" << 0 << 0; +      if (Method) +        S.Diag(Method->getLocation(), diag::note_method_declared_at) +          << Method->getDeclName(); +    } +  } +} +  /// \brief Build an Objective-C class message expression.  ///  /// This routine takes care of both normal class messages and @@ -2146,7 +2214,8 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,    if (CheckMessageArgumentTypes(ReceiverType, MultiExprArg(Args, NumArgs),                                  Sel, SelectorLocs,                                  Method, true, -                                SuperLoc.isValid(), LBracLoc, RBracLoc,  +                                SuperLoc.isValid(), LBracLoc, RBracLoc, +                                SourceRange(),                                  ReturnType, VK))      return ExprError(); @@ -2154,7 +2223,32 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,        RequireCompleteType(LBracLoc, Method->getReturnType(),                            diag::err_illegal_message_expr_incomplete_type))      return ExprError(); - +   +  // Warn about explicit call of +initialize on its own class. But not on 'super'. +  if (Method && Method->getMethodFamily() == OMF_initialize) { +    if (!SuperLoc.isValid()) { +      const ObjCInterfaceDecl *ID = +        dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()); +      if (ID == Class) { +        Diag(Loc, diag::warn_direct_initialize_call); +        Diag(Method->getLocation(), diag::note_method_declared_at) +          << Method->getDeclName(); +      } +    } +    else if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { +      // [super initialize] is allowed only within an +initialize implementation +      if (CurMeth->getMethodFamily() != OMF_initialize) { +        Diag(Loc, diag::warn_direct_super_initialize_call); +        Diag(Method->getLocation(), diag::note_method_declared_at) +          << Method->getDeclName(); +        Diag(CurMeth->getLocation(), diag::note_method_declared_at) +        << CurMeth->getDeclName(); +      } +    } +  } +   +  DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs); +      // Construct the appropriate ObjCMessageExpr.    ObjCMessageExpr *Result;    if (SuperLoc.isValid()) @@ -2354,11 +2448,19 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,          Method = LookupFactoryMethodInGlobalPool(Sel,                                                    SourceRange(LBracLoc,RBracLoc),                                                   receiverIsId); +      if (Method) { +        if (ObjCMethodDecl *BestMethod = +              SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod())) +          Method = BestMethod; +        if (!AreMultipleMethodsInGlobalPool(Sel, Method->isInstanceMethod())) +          DiagnoseUseOfDecl(Method, SelLoc); +      }      } else if (ReceiverType->isObjCClassType() ||                 ReceiverType->isObjCQualifiedClassType()) {        // Handle messages to Class. -      // We allow sending a message to a qualified Class ("Class<foo>"), which  -      // is ok as long as one of the protocols implements the selector (if not, warn). +      // We allow sending a message to a qualified Class ("Class<foo>"), which +      // is ok as long as one of the protocols implements the selector (if not, +      // warn).        if (const ObjCObjectPointerType *QClassTy               = ReceiverType->getAsObjCQualifiedClassType()) {          // Search protocols for class methods. @@ -2405,6 +2507,10 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,                        << Sel << SourceRange(LBracLoc, RBracLoc);                    }              } +            if (Method) +              if (ObjCMethodDecl *BestMethod = +                  SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod())) +                Method = BestMethod;            }          }        } @@ -2543,7 +2649,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,    if (CheckMessageArgumentTypes(ReceiverType, MultiExprArg(Args, NumArgs),                                  Sel, SelectorLocs, Method,                                  ClassMessage, SuperLoc.isValid(),  -                                LBracLoc, RBracLoc, ReturnType, VK)) +                                LBracLoc, RBracLoc, RecRange, ReturnType, VK))      return ExprError();    if (Method && !Method->getReturnType()->isVoidType() && @@ -2568,6 +2674,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,      case OMF_mutableCopy:      case OMF_new:      case OMF_self: +    case OMF_initialize:        break;      case OMF_dealloc: @@ -2630,6 +2737,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,      }    } +  DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs); +      // Construct the appropriate ObjCMessageExpr instance.    ObjCMessageExpr *Result;    if (SuperLoc.isValid()) @@ -3296,6 +3405,9 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,      if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {        if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {          HadTheAttribute = true; +        if (Parm->isStr("id")) +          return true; +                  NamedDecl *Target = nullptr;          // Check for an existing type with this name.          LookupResult R(S, DeclarationName(Parm), SourceLocation(), diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 06ca9aed6a87..569ef307474f 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -466,11 +466,15 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,      //   members in the aggregate, then each member not explicitly initialized      //   shall be initialized from its brace-or-equal-initializer [...]      if (Field->hasInClassInitializer()) { -      Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, Loc, Field); +      ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field); +      if (DIE.isInvalid()) { +        hadError = true; +        return; +      }        if (Init < NumInits) -        ILE->setInit(Init, DIE); +        ILE->setInit(Init, DIE.get());        else { -        ILE->updateInit(SemaRef.Context, Init, DIE); +        ILE->updateInit(SemaRef.Context, Init, DIE.get());          RequiresSecondPass = true;        }        return; @@ -1555,10 +1559,11 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,        }      } -    // Value-initialize the first named member of the union. +    // Value-initialize the first member of the union that isn't an unnamed +    // bitfield.      for (RecordDecl::field_iterator FieldEnd = RD->field_end();           Field != FieldEnd; ++Field) { -      if (Field->getDeclName()) { +      if (!Field->isUnnamedBitfield()) {          if (VerifyOnly)            CheckEmptyInitializable(                InitializedEntity::InitializeMember(*Field, &Entity), @@ -1734,24 +1739,6 @@ static void ExpandAnonymousFieldDesignator(Sema &SemaRef,                          &Replacements[0] + Replacements.size());  } -/// \brief Given an implicit anonymous field, search the IndirectField that -///  corresponds to FieldName. -static IndirectFieldDecl *FindIndirectFieldDesignator(FieldDecl *AnonField, -                                                 IdentifierInfo *FieldName) { -  if (!FieldName) -    return nullptr; - -  assert(AnonField->isAnonymousStructOrUnion()); -  Decl *NextDecl = AnonField->getNextDeclInContext(); -  while (IndirectFieldDecl *IF =  -          dyn_cast_or_null<IndirectFieldDecl>(NextDecl)) { -    if (FieldName == IF->getAnonField()->getIdentifier()) -      return IF; -    NextDecl = NextDecl->getNextDeclInContext(); -  } -  return nullptr; -} -  static DesignatedInitExpr *CloneDesignatedInitExpr(Sema &SemaRef,                                                     DesignatedInitExpr *DIE) {    unsigned NumIndexExprs = DIE->getNumSubExprs() - 1; @@ -1892,103 +1879,76 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,        return true;      } -    // Note: we perform a linear search of the fields here, despite -    // the fact that we have a faster lookup method, because we always -    // need to compute the field's index.      FieldDecl *KnownField = D->getField(); -    IdentifierInfo *FieldName = D->getFieldName(); -    unsigned FieldIndex = 0; -    RecordDecl::field_iterator -      Field = RT->getDecl()->field_begin(), -      FieldEnd = RT->getDecl()->field_end(); -    for (; Field != FieldEnd; ++Field) { -      if (Field->isUnnamedBitfield()) -        continue; - -      // If we find a field representing an anonymous field, look in the -      // IndirectFieldDecl that follow for the designated initializer. -      if (!KnownField && Field->isAnonymousStructOrUnion()) { -        if (IndirectFieldDecl *IF = -            FindIndirectFieldDesignator(*Field, FieldName)) { +    if (!KnownField) { +      IdentifierInfo *FieldName = D->getFieldName(); +      DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName); +      for (NamedDecl *ND : Lookup) { +        if (auto *FD = dyn_cast<FieldDecl>(ND)) { +          KnownField = FD; +          break; +        } +        if (auto *IFD = dyn_cast<IndirectFieldDecl>(ND)) {            // In verify mode, don't modify the original.            if (VerifyOnly)              DIE = CloneDesignatedInitExpr(SemaRef, DIE); -          ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IF); +          ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IFD);            D = DIE->getDesignator(DesigIdx); +          KnownField = cast<FieldDecl>(*IFD->chain_begin());            break;          }        } -      if (KnownField && KnownField == *Field) -        break; -      if (FieldName && FieldName == Field->getIdentifier()) -        break; - -      ++FieldIndex; -    } +      if (!KnownField) { +        if (VerifyOnly) { +          ++Index; +          return true;  // No typo correction when just trying this out. +        } -    if (Field == FieldEnd) { -      if (VerifyOnly) { -        ++Index; -        return true; // No typo correction when just trying this out. -      } +        // Name lookup found something, but it wasn't a field. +        if (!Lookup.empty()) { +          SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield) +            << FieldName; +          SemaRef.Diag(Lookup.front()->getLocation(), +                       diag::note_field_designator_found); +          ++Index; +          return true; +        } -      // There was no normal field in the struct with the designated -      // name. Perform another lookup for this name, which may find -      // something that we can't designate (e.g., a member function), -      // may find nothing, or may find a member of an anonymous -      // struct/union. -      DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName); -      FieldDecl *ReplacementField = nullptr; -      if (Lookup.empty()) { -        // Name lookup didn't find anything. Determine whether this -        // was a typo for another field name. -        FieldInitializerValidatorCCC Validator(RT->getDecl()); +        // Name lookup didn't find anything. +        // Determine whether this was a typo for another field name.          if (TypoCorrection Corrected = SemaRef.CorrectTypo(                  DeclarationNameInfo(FieldName, D->getFieldLoc()), -                Sema::LookupMemberName, /*Scope=*/ nullptr, /*SS=*/ nullptr, -                Validator, Sema::CTK_ErrorRecovery, RT->getDecl())) { +                Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, +                llvm::make_unique<FieldInitializerValidatorCCC>(RT->getDecl()), +                Sema::CTK_ErrorRecovery, RT->getDecl())) {            SemaRef.diagnoseTypo(                Corrected,                SemaRef.PDiag(diag::err_field_designator_unknown_suggest) -                  << FieldName << CurrentObjectType); -          ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>(); +                << FieldName << CurrentObjectType); +          KnownField = Corrected.getCorrectionDeclAs<FieldDecl>();            hadError = true;          } else { +          // Typo correction didn't find anything.            SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)              << FieldName << CurrentObjectType;            ++Index;            return true;          }        } +    } -      if (!ReplacementField) { -        // Name lookup found something, but it wasn't a field. -        SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield) -          << FieldName; -        SemaRef.Diag(Lookup.front()->getLocation(), -                      diag::note_field_designator_found); -        ++Index; -        return true; -      } - -      if (!KnownField) { -        // The replacement field comes from typo correction; find it -        // in the list of fields. -        FieldIndex = 0; -        Field = RT->getDecl()->field_begin(); -        for (; Field != FieldEnd; ++Field) { -          if (Field->isUnnamedBitfield()) -            continue; - -          if (ReplacementField == *Field || -              Field->getIdentifier() == ReplacementField->getIdentifier()) -            break; - -          ++FieldIndex; -        } -      } +    unsigned FieldIndex = 0; +    for (auto *FI : RT->getDecl()->fields()) { +      if (FI->isUnnamedBitfield()) +        continue; +      if (KnownField == FI) +        break; +      ++FieldIndex;      } +    RecordDecl::field_iterator Field = +        RecordDecl::field_iterator(DeclContext::decl_iterator(KnownField)); +      // All of the fields of a union are located at the same place in      // the initializer list.      if (RT->getDecl()->isUnion()) { @@ -5537,18 +5497,18 @@ static void performLifetimeExtension(Expr *Init,  static bool  performReferenceExtension(Expr *Init,                            const InitializedEntity *ExtendingEntity) { -  if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) { -    if (ILE->getNumInits() == 1 && ILE->isGLValue()) { -      // This is just redundant braces around an initializer. Step over it. -      Init = ILE->getInit(0); -    } -  } -    // Walk past any constructs which we can lifetime-extend across.    Expr *Old;    do {      Old = Init; +    if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) { +      if (ILE->getNumInits() == 1 && ILE->isGLValue()) { +        // This is just redundant braces around an initializer. Step over it. +        Init = ILE->getInit(0); +      } +    } +      // Step over any subobject adjustments; we may have a materialized      // temporary inside them.      SmallVector<const Expr *, 2> CommaLHSs; @@ -6476,12 +6436,45 @@ static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,      return diagnoseListInit(S, HiddenArray, InitList);    } +  if (DestType->isReferenceType()) { +    // A list-initialization failure for a reference means that we tried to +    // create a temporary of the inner type (per [dcl.init.list]p3.6) and the +    // inner initialization failed. +    QualType T = DestType->getAs<ReferenceType>()->getPointeeType(); +    diagnoseListInit(S, InitializedEntity::InitializeTemporary(T), InitList); +    SourceLocation Loc = InitList->getLocStart(); +    if (auto *D = Entity.getDecl()) +      Loc = D->getLocation(); +    S.Diag(Loc, diag::note_in_reference_temporary_list_initializer) << T; +    return; +  } +    InitListChecker DiagnoseInitList(S, Entity, InitList, DestType,                                     /*VerifyOnly=*/false);    assert(DiagnoseInitList.HadError() &&           "Inconsistent init list check result.");  } +/// Prints a fixit for adding a null initializer for |Entity|. Call this only +/// right after emitting a diagnostic. +static void maybeEmitZeroInitializationFixit(Sema &S, +                                             InitializationSequence &Sequence, +                                             const InitializedEntity &Entity) { +  if (Entity.getKind() != InitializedEntity::EK_Variable) +    return; + +  VarDecl *VD = cast<VarDecl>(Entity.getDecl()); +  if (VD->getInit() || VD->getLocEnd().isMacroID()) +    return; + +  QualType VariableTy = VD->getType().getCanonicalType(); +  SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd()); +  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc); + +  S.Diag(Loc, diag::note_add_initializer) +      << VD << FixItHint::CreateInsertion(Loc, Init); +} +  bool InitializationSequence::Diagnose(Sema &S,                                        const InitializedEntity &Entity,                                        const InitializationKind &Kind, @@ -6812,7 +6805,8 @@ bool InitializationSequence::Diagnose(Sema &S,          << Entity.getName();      } else {        S.Diag(Kind.getLocation(), diag::err_default_init_const) -        << DestType << (bool)DestType->getAs<RecordType>(); +          << DestType << (bool)DestType->getAs<RecordType>(); +      maybeEmitZeroInitializationFixit(S, *this, Entity);      }      break; diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 0cf4ed7c6081..90a81f4ec452 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -617,7 +617,7 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {    // If it was ever a placeholder, it had to been deduced to DependentTy.    assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType());  -  // C++ Core Issue #975, proposed resolution: +  // C++ core issue 975:    //   If a lambda-expression does not include a trailing-return-type,    //   it is as if the trailing-return-type denotes the following type:    //     - if there are no return statements in the compound-statement, @@ -631,6 +631,10 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {    //       same, that common type;    //     - otherwise, the program is ill-formed.    // +  // C++ core issue 1048 additionally removes top-level cv-qualifiers +  // from the types of returned expressions to match the C++14 auto +  // deduction rules. +  //    // In addition, in blocks in non-C++ modes, if all of the return    // statements are enumerator-like expressions of some type T, where    // T has a name for linkage, then we infer the return type of the @@ -679,7 +683,8 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {      const ReturnStmt *RS = *I;      const Expr *RetE = RS->getRetValue(); -    QualType ReturnType = (RetE ? RetE->getType() : Context.VoidTy); +    QualType ReturnType = +        (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType();      if (Context.hasSameType(ReturnType, CSI.ReturnType))        continue; @@ -873,7 +878,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,      // We don't do this before C++1y, because we don't support deduced return      // types there.      QualType DefaultTypeForNoTrailingReturn = -        getLangOpts().CPlusPlus1y ? Context.getAutoDeductType() +        getLangOpts().CPlusPlus14 ? Context.getAutoDeductType()                                    : Context.DependentTy;      QualType MethodTy =          Context.getFunctionType(DefaultTypeForNoTrailingReturn, None, EPI); @@ -999,7 +1004,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,      VarDecl *Var = nullptr;      if (C->Init.isUsable()) { -      Diag(C->Loc, getLangOpts().CPlusPlus1y +      Diag(C->Loc, getLangOpts().CPlusPlus14                         ? diag::warn_cxx11_compat_init_capture                         : diag::ext_init_capture); @@ -1049,8 +1054,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,        if (R.empty()) {          // FIXME: Disable corrections that would add qualification?          CXXScopeSpec ScopeSpec; -        DeclFilterCCC<VarDecl> Validator; -        if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator)) +        if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, +                                llvm::make_unique<DeclFilterCCC<VarDecl>>()))            continue;        } @@ -1062,7 +1067,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,      // C++11 [expr.prim.lambda]p8:      //   An identifier or this shall not appear more than once in a      //   lambda-capture. -    if (!CaptureNames.insert(C->Id)) { +    if (!CaptureNames.insert(C->Id).second) {        if (Var && LSI->isCaptured(Var)) {          Diag(C->Loc, diag::err_capture_more_than_once)              << C->Id << SourceRange(LSI->getCapture(Var).getLocation()) @@ -1414,6 +1419,12 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,                                                           /*isImplicit=*/true));          continue;        } +      if (From.isVLATypeCapture()) { +        Captures.push_back( +            LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType)); +        CaptureInits.push_back(nullptr); +        continue; +      }        VarDecl *Var = From.getVariable();        LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef; @@ -1451,7 +1462,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,      // different machinery.      // FIXME: Refactor and Merge the return type deduction machinery.      // FIXME: Assumes current resolution to core issue 975. -    if (LSI->HasImplicitReturnType && !getLangOpts().CPlusPlus1y) { +    if (LSI->HasImplicitReturnType && !getLangOpts().CPlusPlus14) {        deduceClosureReturnType(*LSI);        //   - if there are no return statements in the diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index fe2c8161b871..3445264461f7 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -128,7 +128,7 @@ namespace {      // that contexts be visited from the inside out in order to get      // the effective DCs right.      void visit(DeclContext *DC, DeclContext *EffectiveDC) { -      if (!visited.insert(DC)) +      if (!visited.insert(DC).second)          return;        addUsingDirectives(DC, EffectiveDC); @@ -139,7 +139,7 @@ namespace {      // were declared in the effective DC.      void visit(UsingDirectiveDecl *UD, DeclContext *EffectiveDC) {        DeclContext *NS = UD->getNominatedNamespace(); -      if (!visited.insert(NS)) +      if (!visited.insert(NS).second)          return;        addUsingDirective(UD, EffectiveDC); @@ -154,7 +154,7 @@ namespace {        while (true) {          for (auto UD : DC->using_directives()) {            DeclContext *NS = UD->getNominatedNamespace(); -          if (visited.insert(NS)) { +          if (visited.insert(NS).second) {              addUsingDirective(UD, EffectiveDC);              queue.push_back(NS);            } @@ -285,7 +285,7 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,  }  void LookupResult::configure() { -  IDNS = getIDNS(LookupKind, SemaRef.getLangOpts().CPlusPlus, +  IDNS = getIDNS(LookupKind, getSema().getLangOpts().CPlusPlus,                   isForRedeclaration());    // If we're looking for one of the allocation or deallocation @@ -296,7 +296,7 @@ void LookupResult::configure() {    case OO_Delete:    case OO_Array_New:    case OO_Array_Delete: -    SemaRef.DeclareGlobalNewDelete(); +    getSema().DeclareGlobalNewDelete();      break;    default: @@ -307,7 +307,7 @@ void LookupResult::configure() {    // up being declared.    if (IdentifierInfo *Id = NameInfo.getName().getAsIdentifierInfo()) {      if (unsigned BuiltinID = Id->getBuiltinID()) { -      if (!SemaRef.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) +      if (!getSema().Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))          AllowHidden = true;      }    } @@ -400,8 +400,8 @@ void LookupResult::resolveKind() {      // canonical type.      if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {        if (!TD->getDeclContext()->isRecord()) { -        QualType T = SemaRef.Context.getTypeDeclType(TD); -        if (!UniqueTypes.insert(SemaRef.Context.getCanonicalType(T))) { +        QualType T = getSema().Context.getTypeDeclType(TD); +        if (!UniqueTypes.insert(getSema().Context.getCanonicalType(T)).second) {            // The type is not unique; pull something off the back and continue            // at this index.            Decls[I] = Decls[--N]; @@ -410,7 +410,7 @@ void LookupResult::resolveKind() {        }      } -    if (!Unique.insert(D)) { +    if (!Unique.insert(D).second) {        // If it's not unique, pull something off the back (and        // continue at this index).        Decls[I] = Decls[--N]; @@ -735,8 +735,7 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {      // FIXME: Calling convention!      FunctionProtoType::ExtProtoInfo EPI = ConvProto->getExtProtoInfo();      EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CC_C); -    EPI.ExceptionSpecType = EST_None; -    EPI.NumExceptions = 0; +    EPI.ExceptionSpec = EST_None;      QualType ExpectedType        = R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(),                                              None, EPI); @@ -1176,21 +1175,8 @@ static Module *getDefiningModule(Decl *Entity) {      if (FunctionDecl *Pattern = FD->getTemplateInstantiationPattern())        Entity = Pattern;    } else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Entity)) { -    // If it's a class template specialization, find the template or partial -    // specialization from which it was instantiated. -    if (ClassTemplateSpecializationDecl *SpecRD = -            dyn_cast<ClassTemplateSpecializationDecl>(RD)) { -      llvm::PointerUnion<ClassTemplateDecl*, -                         ClassTemplatePartialSpecializationDecl*> From = -          SpecRD->getInstantiatedFrom(); -      if (ClassTemplateDecl *FromTemplate = From.dyn_cast<ClassTemplateDecl*>()) -        Entity = FromTemplate->getTemplatedDecl(); -      else if (From) -        Entity = From.get<ClassTemplatePartialSpecializationDecl*>(); -      // Otherwise, it's an explicit specialization. -    } else if (MemberSpecializationInfo *MSInfo = -                   RD->getMemberSpecializationInfo()) -      Entity = getInstantiatedFrom(RD, MSInfo); +    if (CXXRecordDecl *Pattern = RD->getTemplateInstantiationPattern()) +      Entity = Pattern;    } else if (EnumDecl *ED = dyn_cast<EnumDecl>(Entity)) {      if (MemberSpecializationInfo *MSInfo = ED->getMemberSpecializationInfo())        Entity = getInstantiatedFrom(ED, MSInfo); @@ -1279,7 +1265,7 @@ static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {  }  NamedDecl *LookupResult::getAcceptableDeclSlow(NamedDecl *D) const { -  return findAcceptableDecl(SemaRef, D); +  return findAcceptableDecl(getSema(), D);  }  /// @brief Perform unqualified name lookup starting from a given @@ -1466,7 +1452,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R,    // with its using-children.    for (auto *I : UsingDirectives) {      NamespaceDecl *ND = I->getNominatedNamespace()->getOriginalNamespace(); -    if (Visited.insert(ND)) +    if (Visited.insert(ND).second)        Queue.push_back(ND);    } @@ -1514,7 +1500,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R,      for (auto I : ND->using_directives()) {        NamespaceDecl *Nom = I->getNominatedNamespace(); -      if (Visited.insert(Nom)) +      if (Visited.insert(Nom).second)          Queue.push_back(Nom);      }    } @@ -1776,6 +1762,31 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,    return true;  } +/// \brief Performs qualified name lookup or special type of lookup for +/// "__super::" scope specifier. +/// +/// This routine is a convenience overload meant to be called from contexts +/// that need to perform a qualified name lookup with an optional C++ scope +/// specifier that might require special kind of lookup. +/// +/// \param R captures both the lookup criteria and any lookup results found. +/// +/// \param LookupCtx The context in which qualified name lookup will +/// search. +/// +/// \param SS An optional C++ scope-specifier. +/// +/// \returns true if lookup succeeded, false if it failed. +bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, +                               CXXScopeSpec &SS) { +  auto *NNS = SS.getScopeRep(); +  if (NNS && NNS->getKind() == NestedNameSpecifier::Super) +    return LookupInSuper(R, NNS->getAsRecordDecl()); +  else + +    return LookupQualifiedName(R, LookupCtx); +} +  /// @brief Performs name lookup for a name that was parsed in the  /// source code, and may contain a C++ scope specifier.  /// @@ -1783,7 +1794,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,  /// contexts that receive a name and an optional C++ scope specifier  /// (e.g., "N::M::x"). It will then perform either qualified or  /// unqualified name lookup (with LookupQualifiedName or LookupName, -/// respectively) on the given name and return those results. +/// respectively) on the given name and return those results. It will +/// perform a special type of lookup for "__super::" scope specifier.  ///  /// @param S        The scope from which unqualified name lookup will  /// begin. @@ -1803,6 +1815,10 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,    }    if (SS && SS->isSet()) { +    NestedNameSpecifier *NNS = SS->getScopeRep(); +    if (NNS->getKind() == NestedNameSpecifier::Super) +      return LookupInSuper(R, NNS->getAsRecordDecl()); +      if (DeclContext *DC = computeDeclContext(*SS, EnteringContext)) {        // We have resolved the scope specifier to a particular declaration        // contex, and will perform name lookup in that context. @@ -1825,6 +1841,30 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,    return LookupName(R, S, AllowBuiltinCreation);  } +/// \brief Perform qualified name lookup into all base classes of the given +/// class. +/// +/// \param R captures both the lookup criteria and any lookup results found. +/// +/// \param Class The context in which qualified name lookup will +/// search. Name lookup will search in all base classes merging the results. +/// +/// @returns True if any decls were found (but possibly ambiguous) +bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { +  for (const auto &BaseSpec : Class->bases()) { +    CXXRecordDecl *RD = cast<CXXRecordDecl>( +        BaseSpec.getType()->castAs<RecordType>()->getDecl()); +    LookupResult Result(*this, R.getLookupNameInfo(), R.getLookupKind()); +	Result.setBaseObjectType(Context.getRecordType(Class)); +    LookupQualifiedName(Result, RD); +    for (auto *Decl : Result) +      R.addDecl(Decl); +  } + +  R.resolveKind(); + +  return !R.empty(); +}  /// \brief Produce a diagnostic describing the ambiguity that resulted  /// from name lookup. @@ -2024,7 +2064,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,    // FIXME: That's not correct, we may have added this class only because it    // was the enclosing class of another class, and in that case we won't have    // added its base classes yet. -  if (!Result.Classes.insert(Class)) +  if (!Result.Classes.insert(Class).second)      return;    // -- If T is a template-id, its associated namespaces and classes are @@ -2073,7 +2113,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,        if (!BaseType)          continue;        CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl()); -      if (Result.Classes.insert(BaseDecl)) { +      if (Result.Classes.insert(BaseDecl).second) {          // Find the associated namespace for this base class.          DeclContext *BaseCtx = BaseDecl->getDeclContext();          CollectEnclosingNamespace(Result.Namespaces, BaseCtx); @@ -2875,7 +2915,7 @@ public:    /// \brief Determine whether we have already visited this context    /// (and, if not, note that we are going to visit that context now).    bool visitedContext(DeclContext *Ctx) { -    return !VisitedContexts.insert(Ctx); +    return !VisitedContexts.insert(Ctx).second;    }    bool alreadyVisitedContext(DeclContext *Ctx) { @@ -3263,6 +3303,49 @@ static void LookupPotentialTypoResult(Sema &SemaRef,                                        bool isObjCIvarLookup,                                        bool FindHidden); +/// \brief Check whether the declarations found for a typo correction are +/// visible, and if none of them are, convert the correction to an 'import +/// a module' correction. +static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { +  if (TC.begin() == TC.end()) +    return; + +  TypoCorrection::decl_iterator DI = TC.begin(), DE = TC.end(); + +  for (/**/; DI != DE; ++DI) +    if (!LookupResult::isVisible(SemaRef, *DI)) +      break; +  // Nothing to do if all decls are visible. +  if (DI == DE) +    return; + +  llvm::SmallVector<NamedDecl*, 4> NewDecls(TC.begin(), DI); +  bool AnyVisibleDecls = !NewDecls.empty(); + +  for (/**/; DI != DE; ++DI) { +    NamedDecl *VisibleDecl = *DI; +    if (!LookupResult::isVisible(SemaRef, *DI)) +      VisibleDecl = findAcceptableDecl(SemaRef, *DI); + +    if (VisibleDecl) { +      if (!AnyVisibleDecls) { +        // Found a visible decl, discard all hidden ones. +        AnyVisibleDecls = true; +        NewDecls.clear(); +      } +      NewDecls.push_back(VisibleDecl); +    } else if (!AnyVisibleDecls && !(*DI)->isModulePrivate()) +      NewDecls.push_back(*DI); +  } + +  if (NewDecls.empty()) +    TC = TypoCorrection(); +  else { +    TC.setCorrectionDecls(NewDecls); +    TC.setRequiresImport(!AnyVisibleDecls); +  } +} +  // Fill the supplied vector with the IdentifierInfo pointers for each piece of  // the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",  // fill the vector with the IdentifierInfo pointers for "foo" and "bar"). @@ -3297,6 +3380,7 @@ static void getNestedNameSpecifierIdentifiers(      break;    case NestedNameSpecifier::Global: +  case NestedNameSpecifier::Super:      return;    } @@ -3304,157 +3388,6 @@ static void getNestedNameSpecifierIdentifiers(      Identifiers.push_back(II);  } -namespace { - -static const unsigned MaxTypoDistanceResultSets = 5; - -class TypoCorrectionConsumer : public VisibleDeclConsumer { -  typedef SmallVector<TypoCorrection, 1> TypoResultList; -  typedef llvm::StringMap<TypoResultList> TypoResultsMap; -  typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap; - -public: -  explicit TypoCorrectionConsumer(Sema &SemaRef, -                                  const DeclarationNameInfo &TypoName, -                                  Sema::LookupNameKind LookupKind, -                                  Scope *S, CXXScopeSpec *SS, -                                  CorrectionCandidateCallback &CCC, -                                  DeclContext *MemberContext, -                                  bool EnteringContext) -      : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S), -        SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext), -        Result(SemaRef, TypoName, LookupKind), -        Namespaces(SemaRef.Context, SemaRef.CurContext, SS), -        EnteringContext(EnteringContext), SearchNamespaces(false) { -    Result.suppressDiagnostics(); -  } - -  bool includeHiddenDecls() const override { return true; } - -  // Methods for adding potential corrections to the consumer. -  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, -                 bool InBaseClass) override; -  void FoundName(StringRef Name); -  void addKeywordResult(StringRef Keyword); -  void addCorrection(TypoCorrection Correction); - -  bool empty() const { return CorrectionResults.empty(); } - -  /// \brief Return the list of TypoCorrections for the given identifier from -  /// the set of corrections that have the closest edit distance, if any. -  TypoResultList &operator[](StringRef Name) { -    return CorrectionResults.begin()->second[Name]; -  } - -  /// \brief Return the edit distance of the corrections that have the -  /// closest/best edit distance from the original typop. -  unsigned getBestEditDistance(bool Normalized) { -    if (CorrectionResults.empty()) -      return (std::numeric_limits<unsigned>::max)(); - -    unsigned BestED = CorrectionResults.begin()->first; -    return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED; -  } - -  /// \brief Set-up method to add to the consumer the set of namespaces to use -  /// in performing corrections to nested name specifiers. This method also -  /// implicitly adds all of the known classes in the current AST context to the -  /// to the consumer for correcting nested name specifiers. -  void -  addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces); - -  /// \brief Return the next typo correction that passes all internal filters -  /// and is deemed valid by the consumer's CorrectionCandidateCallback, -  /// starting with the corrections that have the closest edit distance. An -  /// empty TypoCorrection is returned once no more viable corrections remain -  /// in the consumer. -  TypoCorrection getNextCorrection(); - -private: -  class NamespaceSpecifierSet { -    struct SpecifierInfo { -      DeclContext* DeclCtx; -      NestedNameSpecifier* NameSpecifier; -      unsigned EditDistance; -    }; - -    typedef SmallVector<DeclContext*, 4> DeclContextList; -    typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList; - -    ASTContext &Context; -    DeclContextList CurContextChain; -    std::string CurNameSpecifier; -    SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers; -    SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers; -    bool isSorted; - -    SpecifierInfoList Specifiers; -    llvm::SmallSetVector<unsigned, 4> Distances; -    llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap; - -    /// \brief Helper for building the list of DeclContexts between the current -    /// context and the top of the translation unit -    static DeclContextList buildContextChain(DeclContext *Start); - -    void sortNamespaces(); - -    unsigned buildNestedNameSpecifier(DeclContextList &DeclChain, -                                      NestedNameSpecifier *&NNS); - -   public: -    NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext, -                          CXXScopeSpec *CurScopeSpec); - -    /// \brief Add the DeclContext (a namespace or record) to the set, computing -    /// the corresponding NestedNameSpecifier and its distance in the process. -    void addNameSpecifier(DeclContext *Ctx); - -    typedef SpecifierInfoList::iterator iterator; -    iterator begin() { -      if (!isSorted) sortNamespaces(); -      return Specifiers.begin(); -    } -    iterator end() { return Specifiers.end(); } -  }; - -  void addName(StringRef Name, NamedDecl *ND, -               NestedNameSpecifier *NNS = nullptr, bool isKeyword = false); - -  /// \brief Find any visible decls for the given typo correction candidate. -  /// If none are found, it to the set of candidates for which qualified lookups -  /// will be performed to find possible nested name specifier changes. -  bool resolveCorrection(TypoCorrection &Candidate); - -  /// \brief Perform qualified lookups on the queued set of typo correction -  /// candidates and add the nested name specifier changes to each candidate if -  /// a lookup succeeds (at which point the candidate will be returned to the -  /// main pool of potential corrections). -  void performQualifiedLookups(); - -  /// \brief The name written that is a typo in the source. -  IdentifierInfo *Typo; - -  /// \brief The results found that have the smallest edit distance -  /// found (so far) with the typo name. -  /// -  /// The pointer value being set to the current DeclContext indicates -  /// whether there is a keyword with this name. -  TypoEditDistanceMap CorrectionResults; - -  Sema &SemaRef; -  Scope *S; -  CXXScopeSpec *SS; -  CorrectionCandidateCallback &CorrectionValidator; -  DeclContext *MemberContext; -  LookupResult Result; -  NamespaceSpecifierSet Namespaces; -  SmallVector<TypoCorrection, 2> QualifiedResults; -  bool EnteringContext; -  bool SearchNamespaces; -}; - -} -  void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,                                         DeclContext *Ctx, bool InBaseClass) {    // Don't consider hidden names for typo correction. @@ -3506,9 +3439,12 @@ void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,    TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);    if (isKeyword) TC.makeKeyword(); +  TC.setCorrectionRange(nullptr, Result.getLookupNameInfo());    addCorrection(TC);  } +static const unsigned MaxTypoDistanceResultSets = 5; +  void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {    StringRef TypoStr = Typo->getName();    StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName(); @@ -3521,9 +3457,11 @@ void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {      return;    // If the correction is resolved but is not viable, ignore it. -  if (Correction.isResolved() && -      !isCandidateViable(CorrectionValidator, Correction)) -    return; +  if (Correction.isResolved()) { +    checkCorrectionVisibility(SemaRef, Correction); +    if (!Correction || !isCandidateViable(*CorrectionValidator, Correction)) +      return; +  }    TypoResultList &CList =        CorrectionResults[Correction.getEditDistance(false)][Name]; @@ -3577,7 +3515,11 @@ void TypoCorrectionConsumer::addNamespaces(    }  } -TypoCorrection TypoCorrectionConsumer::getNextCorrection() { +const TypoCorrection &TypoCorrectionConsumer::getNextCorrection() { +  if (++CurrentTCIndex < ValidatedCorrections.size()) +    return ValidatedCorrections[CurrentTCIndex]; + +  CurrentTCIndex = ValidatedCorrections.size();    while (!CorrectionResults.empty()) {      auto DI = CorrectionResults.begin();      if (DI->second.empty()) { @@ -3593,20 +3535,22 @@ TypoCorrection TypoCorrectionConsumer::getNextCorrection() {      }      TypoCorrection TC = RI->second.pop_back_val(); -    if (TC.isResolved() || resolveCorrection(TC)) -      return TC; +    if (TC.isResolved() || TC.requiresImport() || resolveCorrection(TC)) { +      ValidatedCorrections.push_back(TC); +      return ValidatedCorrections[CurrentTCIndex]; +    }    } -  return TypoCorrection(); +  return ValidatedCorrections[0];  // The empty correction.  }  bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {    IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();    DeclContext *TempMemberContext = MemberContext; -  CXXScopeSpec *TempSS = SS; +  CXXScopeSpec *TempSS = SS.get();  retry_lookup:    LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext,                              EnteringContext, -                            CorrectionValidator.IsObjCIvarLookup, +                            CorrectionValidator->IsObjCIvarLookup,                              Name == Typo && !Candidate.WillReplaceSpecifier());    switch (Result.getResultKind()) {    case LookupResult::NotFound: @@ -3620,7 +3564,7 @@ retry_lookup:      }      if (TempMemberContext) {        if (SS && !TempSS) -        TempSS = SS; +        TempSS = SS.get();        TempMemberContext = nullptr;        goto retry_lookup;      } @@ -3637,11 +3581,13 @@ retry_lookup:      // Store all of the Decls for overloaded symbols      for (auto *TRD : Result)        Candidate.addCorrectionDecl(TRD); -    if (!isCandidateViable(CorrectionValidator, Candidate)) { +    checkCorrectionVisibility(SemaRef, Candidate); +    if (!isCandidateViable(*CorrectionValidator, Candidate)) {        if (SearchNamespaces)          QualifiedResults.push_back(Candidate);        break;      } +    Candidate.setCorrectionRange(TempSS, Result.getLookupNameInfo());      return true;    }    return false; @@ -3707,8 +3653,10 @@ void TypoCorrectionConsumer::performQualifiedLookups() {                                          TRD.getPair()) == Sema::AR_accessible)              TC.addCorrectionDecl(*TRD);          } -        if (TC.isResolved()) +        if (TC.isResolved()) { +          TC.setCorrectionRange(SS.get(), Result.getLookupNameInfo());            addCorrection(TC); +        }          break;        }        case LookupResult::NotFound: @@ -3856,8 +3804,8 @@ void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(      SmallVector<const IdentifierInfo*, 4> NewNameSpecifierIdentifiers;      getNestedNameSpecifierIdentifiers(NNS, NewNameSpecifierIdentifiers);      NumSpecifiers = llvm::ComputeEditDistance( -        ArrayRef<const IdentifierInfo *>(CurNameSpecifierIdentifiers), -        ArrayRef<const IdentifierInfo *>(NewNameSpecifierIdentifiers)); +        llvm::makeArrayRef(CurNameSpecifierIdentifiers), +        llvm::makeArrayRef(NewNameSpecifierIdentifiers));    }    isSorted = false; @@ -3972,6 +3920,13 @@ static void AddKeywordsToConsumer(Sema &SemaRef,      if (SemaRef.getLangOpts().GNUMode)        Consumer.addKeywordResult("typeof"); +  } else if (CCC.WantFunctionLikeCasts) { +    static const char *const CastableTypeSpecs[] = { +      "char", "double", "float", "int", "long", "short", +      "signed", "unsigned", "void" +    }; +    for (auto *kw : CastableTypeSpecs) +      Consumer.addKeywordResult(kw);    }    if (CCC.WantCXXNamedCasts && SemaRef.getLangOpts().CPlusPlus) { @@ -4063,212 +4018,96 @@ static void AddKeywordsToConsumer(Sema &SemaRef,    }  } -/// \brief Check whether the declarations found for a typo correction are -/// visible, and if none of them are, convert the correction to an 'import -/// a module' correction. -static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { -  if (TC.begin() == TC.end()) -    return; - -  TypoCorrection::decl_iterator DI = TC.begin(), DE = TC.end(); - -  for (/**/; DI != DE; ++DI) -    if (!LookupResult::isVisible(SemaRef, *DI)) -      break; -  // Nothing to do if all decls are visible. -  if (DI == DE) -    return; - -  llvm::SmallVector<NamedDecl*, 4> NewDecls(TC.begin(), DI); -  bool AnyVisibleDecls = !NewDecls.empty(); - -  for (/**/; DI != DE; ++DI) { -    NamedDecl *VisibleDecl = *DI; -    if (!LookupResult::isVisible(SemaRef, *DI)) -      VisibleDecl = findAcceptableDecl(SemaRef, *DI); - -    if (VisibleDecl) { -      if (!AnyVisibleDecls) { -        // Found a visible decl, discard all hidden ones. -        AnyVisibleDecls = true; -        NewDecls.clear(); -      } -      NewDecls.push_back(VisibleDecl); -    } else if (!AnyVisibleDecls && !(*DI)->isModulePrivate()) -      NewDecls.push_back(*DI); -  } - -  if (NewDecls.empty()) -    TC = TypoCorrection(); -  else { -    TC.setCorrectionDecls(NewDecls); -    TC.setRequiresImport(!AnyVisibleDecls); -  } -} - -/// \brief Try to "correct" a typo in the source code by finding -/// visible declarations whose names are similar to the name that was -/// present in the source code. -/// -/// \param TypoName the \c DeclarationNameInfo structure that contains -/// the name that was present in the source code along with its location. -/// -/// \param LookupKind the name-lookup criteria used to search for the name. -/// -/// \param S the scope in which name lookup occurs. -/// -/// \param SS the nested-name-specifier that precedes the name we're -/// looking for, if present. -/// -/// \param CCC A CorrectionCandidateCallback object that provides further -/// validation of typo correction candidates. It also provides flags for -/// determining the set of keywords permitted. -/// -/// \param MemberContext if non-NULL, the context in which to look for -/// a member access expression. -/// -/// \param EnteringContext whether we're entering the context described by -/// the nested-name-specifier SS. -/// -/// \param OPT when non-NULL, the search for visible declarations will -/// also walk the protocols in the qualified interfaces of \p OPT. -/// -/// \returns a \c TypoCorrection containing the corrected name if the typo -/// along with information such as the \c NamedDecl where the corrected name -/// was declared, and any additional \c NestedNameSpecifier needed to access -/// it (C++ only). The \c TypoCorrection is empty if there is no correction. -TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, -                                 Sema::LookupNameKind LookupKind, -                                 Scope *S, CXXScopeSpec *SS, -                                 CorrectionCandidateCallback &CCC, -                                 CorrectTypoKind Mode, -                                 DeclContext *MemberContext, -                                 bool EnteringContext, -                                 const ObjCObjectPointerType *OPT, -                                 bool RecordFailure) { -  // Always let the ExternalSource have the first chance at correction, even -  // if we would otherwise have given up. -  if (ExternalSource) { -    if (TypoCorrection Correction = ExternalSource->CorrectTypo( -        TypoName, LookupKind, S, SS, CCC, MemberContext, EnteringContext, OPT)) -      return Correction; -  } +std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( +    const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, +    Scope *S, CXXScopeSpec *SS, +    std::unique_ptr<CorrectionCandidateCallback> CCC, +    DeclContext *MemberContext, bool EnteringContext, +    const ObjCObjectPointerType *OPT, bool ErrorRecovery) {    if (Diags.hasFatalErrorOccurred() || !getLangOpts().SpellChecking ||        DisableTypoCorrection) -    return TypoCorrection(); +    return nullptr;    // In Microsoft mode, don't perform typo correction in a template member    // function dependent context because it interferes with the "lookup into    // dependent bases of class templates" feature.    if (getLangOpts().MSVCCompat && CurContext->isDependentContext() &&        isa<CXXMethodDecl>(CurContext)) -    return TypoCorrection(); +    return nullptr;    // We only attempt to correct typos for identifiers.    IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo();    if (!Typo) -    return TypoCorrection(); +    return nullptr;    // If the scope specifier itself was invalid, don't try to correct    // typos.    if (SS && SS->isInvalid()) -    return TypoCorrection(); +    return nullptr;    // Never try to correct typos during template deduction or    // instantiation.    if (!ActiveTemplateInstantiations.empty()) -    return TypoCorrection(); +    return nullptr;    // Don't try to correct 'super'.    if (S && S->isInObjcMethodScope() && Typo == getSuperIdentifier()) -    return TypoCorrection(); +    return nullptr;    // Abort if typo correction already failed for this specific typo.    IdentifierSourceLocations::iterator locs = TypoCorrectionFailures.find(Typo);    if (locs != TypoCorrectionFailures.end() &&        locs->second.count(TypoName.getLoc())) -    return TypoCorrection(); +    return nullptr;    // Don't try to correct the identifier "vector" when in AltiVec mode.    // TODO: Figure out why typo correction misbehaves in this case, fix it, and    // remove this workaround.    if (getLangOpts().AltiVec && Typo->isStr("vector")) -    return TypoCorrection(); +    return nullptr; + +  // Provide a stop gap for files that are just seriously broken.  Trying +  // to correct all typos can turn into a HUGE performance penalty, causing +  // some files to take minutes to get rejected by the parser. +  unsigned Limit = getDiagnostics().getDiagnosticOptions().SpellCheckingLimit; +  if (Limit && TyposCorrected >= Limit) +    return nullptr; +  ++TyposCorrected;    // If we're handling a missing symbol error, using modules, and the    // special search all modules option is used, look for a missing import. -  if ((Mode == CTK_ErrorRecovery) &&  getLangOpts().Modules && +  if (ErrorRecovery && getLangOpts().Modules &&        getLangOpts().ModulesSearchAll) {      // The following has the side effect of loading the missing module.      getModuleLoader().lookupMissingImports(Typo->getName(),                                             TypoName.getLocStart());    } -  TypoCorrectionConsumer Consumer(*this, TypoName, LookupKind, S, SS, CCC, -                                  MemberContext, EnteringContext); - -  // If a callback object considers an empty typo correction candidate to be -  // viable, assume it does not do any actual validation of the candidates. -  TypoCorrection EmptyCorrection; -  bool ValidatingCallback = !isCandidateViable(CCC, EmptyCorrection); +  CorrectionCandidateCallback &CCCRef = *CCC; +  auto Consumer = llvm::make_unique<TypoCorrectionConsumer>( +      *this, TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, +      EnteringContext);    // Perform name lookup to find visible, similarly-named entities.    bool IsUnqualifiedLookup = false;    DeclContext *QualifiedDC = MemberContext;    if (MemberContext) { -    LookupVisibleDecls(MemberContext, LookupKind, Consumer); +    LookupVisibleDecls(MemberContext, LookupKind, *Consumer);      // Look in qualified interfaces.      if (OPT) {        for (auto *I : OPT->quals()) -        LookupVisibleDecls(I, LookupKind, Consumer); +        LookupVisibleDecls(I, LookupKind, *Consumer);      }    } else if (SS && SS->isSet()) {      QualifiedDC = computeDeclContext(*SS, EnteringContext);      if (!QualifiedDC) -      return TypoCorrection(); +      return nullptr; -    // Provide a stop gap for files that are just seriously broken.  Trying -    // to correct all typos can turn into a HUGE performance penalty, causing -    // some files to take minutes to get rejected by the parser. -    if (TyposCorrected + UnqualifiedTyposCorrected.size() >= 20) -      return TypoCorrection(); -    ++TyposCorrected; - -    LookupVisibleDecls(QualifiedDC, LookupKind, Consumer); +    LookupVisibleDecls(QualifiedDC, LookupKind, *Consumer);    } else {      IsUnqualifiedLookup = true; -    UnqualifiedTyposCorrectedMap::iterator Cached -      = UnqualifiedTyposCorrected.find(Typo); -    if (Cached != UnqualifiedTyposCorrected.end()) { -      // Add the cached value, unless it's a keyword or fails validation. In the -      // keyword case, we'll end up adding the keyword below. -      if (Cached->second) { -        if (!Cached->second.isKeyword() && -            isCandidateViable(CCC, Cached->second)) { -          // Do not use correction that is unaccessible in the given scope. -          NamedDecl *CorrectionDecl = Cached->second.getCorrectionDecl(); -          DeclarationNameInfo NameInfo(CorrectionDecl->getDeclName(), -                                       CorrectionDecl->getLocation()); -          LookupResult R(*this, NameInfo, LookupOrdinaryName); -          if (LookupName(R, S)) -            Consumer.addCorrection(Cached->second); -        } -      } else { -        // Only honor no-correction cache hits when a callback that will validate -        // correction candidates is not being used. -        if (!ValidatingCallback) -          return TypoCorrection(); -      } -    } -    if (Cached == UnqualifiedTyposCorrected.end()) { -      // Provide a stop gap for files that are just seriously broken.  Trying -      // to correct all typos can turn into a HUGE performance penalty, causing -      // some files to take minutes to get rejected by the parser. -      if (TyposCorrected + UnqualifiedTyposCorrected.size() >= 20) -        return TypoCorrection(); -    }    }    // Determine whether we are going to search in the various namespaces for @@ -4276,17 +4115,13 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,    bool SearchNamespaces      = getLangOpts().CPlusPlus &&        (IsUnqualifiedLookup || (SS && SS->isSet())); -  // In a few cases we *only* want to search for corrections based on just -  // adding or changing the nested name specifier. -  unsigned TypoLen = Typo->getName().size(); -  bool AllowOnlyNNSChanges = TypoLen < 3;    if (IsUnqualifiedLookup || SearchNamespaces) {      // For unqualified lookup, look through all of the names that we have      // seen in this translation unit.      // FIXME: Re-add the ability to skip very unlikely potential corrections.      for (const auto &I : Context.Idents) -      Consumer.FoundName(I.getKey()); +      Consumer->FoundName(I.getKey());      // Walk through identifiers in external identifier sources.      // FIXME: Re-add the ability to skip very unlikely potential corrections. @@ -4298,24 +4133,12 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,          if (Name.empty())            break; -        Consumer.FoundName(Name); +        Consumer->FoundName(Name);        } while (true);      }    } -  AddKeywordsToConsumer(*this, Consumer, S, CCC, SS && SS->isNotEmpty()); - -  // If we haven't found anything, we're done. -  if (Consumer.empty()) -    return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure, -                            IsUnqualifiedLookup); - -  // Make sure the best edit distance (prior to adding any namespace qualifiers) -  // is not more that about a third of the length of the typo's identifier. -  unsigned ED = Consumer.getBestEditDistance(true); -  if (ED > 0 && TypoLen / ED < 3) -    return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure, -                            IsUnqualifiedLookup); +  AddKeywordsToConsumer(*this, *Consumer, S, CCCRef, SS && SS->isNotEmpty());    // Build the NestedNameSpecifiers for the KnownNamespaces, if we're going    // to search those namespaces. @@ -4329,22 +4152,99 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,          KnownNamespaces[N] = true;      } -    Consumer.addNamespaces(KnownNamespaces); +    Consumer->addNamespaces(KnownNamespaces);    } -  TypoCorrection BestTC = Consumer.getNextCorrection(); -  TypoCorrection SecondBestTC = Consumer.getNextCorrection(); +  return Consumer; +} + +/// \brief Try to "correct" a typo in the source code by finding +/// visible declarations whose names are similar to the name that was +/// present in the source code. +/// +/// \param TypoName the \c DeclarationNameInfo structure that contains +/// the name that was present in the source code along with its location. +/// +/// \param LookupKind the name-lookup criteria used to search for the name. +/// +/// \param S the scope in which name lookup occurs. +/// +/// \param SS the nested-name-specifier that precedes the name we're +/// looking for, if present. +/// +/// \param CCC A CorrectionCandidateCallback object that provides further +/// validation of typo correction candidates. It also provides flags for +/// determining the set of keywords permitted. +/// +/// \param MemberContext if non-NULL, the context in which to look for +/// a member access expression. +/// +/// \param EnteringContext whether we're entering the context described by +/// the nested-name-specifier SS. +/// +/// \param OPT when non-NULL, the search for visible declarations will +/// also walk the protocols in the qualified interfaces of \p OPT. +/// +/// \returns a \c TypoCorrection containing the corrected name if the typo +/// along with information such as the \c NamedDecl where the corrected name +/// was declared, and any additional \c NestedNameSpecifier needed to access +/// it (C++ only). The \c TypoCorrection is empty if there is no correction. +TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, +                                 Sema::LookupNameKind LookupKind, +                                 Scope *S, CXXScopeSpec *SS, +                                 std::unique_ptr<CorrectionCandidateCallback> CCC, +                                 CorrectTypoKind Mode, +                                 DeclContext *MemberContext, +                                 bool EnteringContext, +                                 const ObjCObjectPointerType *OPT, +                                 bool RecordFailure) { +  assert(CCC && "CorrectTypo requires a CorrectionCandidateCallback"); + +  // Always let the ExternalSource have the first chance at correction, even +  // if we would otherwise have given up. +  if (ExternalSource) { +    if (TypoCorrection Correction = ExternalSource->CorrectTypo( +        TypoName, LookupKind, S, SS, *CCC, MemberContext, EnteringContext, OPT)) +      return Correction; +  } + +  // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver; +  // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for +  // some instances of CTC_Unknown, while WantRemainingKeywords is true +  // for CTC_Unknown but not for CTC_ObjCMessageReceiver. +  bool ObjCMessageReceiver = CCC->WantObjCSuper && !CCC->WantRemainingKeywords; + +  IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo(); +  auto Consumer = makeTypoCorrectionConsumer( +      TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, +      EnteringContext, OPT, Mode == CTK_ErrorRecovery); + +  if (!Consumer) +    return TypoCorrection(); + +  // If we haven't found anything, we're done. +  if (Consumer->empty()) +    return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure); + +  // Make sure the best edit distance (prior to adding any namespace qualifiers) +  // is not more that about a third of the length of the typo's identifier. +  unsigned ED = Consumer->getBestEditDistance(true); +  unsigned TypoLen = Typo->getName().size(); +  if (ED > 0 && TypoLen / ED < 3) +    return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure); + +  TypoCorrection BestTC = Consumer->getNextCorrection(); +  TypoCorrection SecondBestTC = Consumer->getNextCorrection();    if (!BestTC)      return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);    ED = BestTC.getEditDistance(); -  if (!AllowOnlyNNSChanges && ED > 0 && TypoLen / ED < 3) { +  if (TypoLen >= 3 && ED > 0 && TypoLen / ED < 3) {      // If this was an unqualified lookup and we believe the callback      // object wouldn't have filtered out possible corrections, note      // that no correction was found. -    return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure, -                            IsUnqualifiedLookup && !ValidatingCallback); +    return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);    }    // If only a single name remains, return that result. @@ -4357,28 +4257,19 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,      if (ED == 0 && Result.isKeyword())        return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure); -    // Record the correction for unqualified lookup. -    if (IsUnqualifiedLookup) -      UnqualifiedTyposCorrected[Typo] = Result; -      TypoCorrection TC = Result;      TC.setCorrectionRange(SS, TypoName);      checkCorrectionVisibility(*this, TC);      return TC; -  } -  // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver; -  // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for -  // some instances of CTC_Unknown, while WantRemainingKeywords is true -  // for CTC_Unknown but not for CTC_ObjCMessageReceiver. -  else if (SecondBestTC && CCC.WantObjCSuper && !CCC.WantRemainingKeywords) { +  } else if (SecondBestTC && ObjCMessageReceiver) {      // Prefer 'super' when we're completing in a message-receiver      // context.      if (BestTC.getCorrection().getAsString() != "super") {        if (SecondBestTC.getCorrection().getAsString() == "super")          BestTC = SecondBestTC; -      else if (Consumer["super"].front().isKeyword()) -        BestTC = Consumer["super"].front(); +      else if ((*Consumer)["super"].front().isKeyword()) +        BestTC = (*Consumer)["super"].front();      }      // Don't correct to a keyword that's the same as the typo; the keyword      // wasn't actually in scope. @@ -4386,10 +4277,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,          BestTC.getCorrection().getAsString() != "super")        return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure); -    // Record the correction for unqualified lookup. -    if (IsUnqualifiedLookup) -      UnqualifiedTyposCorrected[Typo] = BestTC; -      BestTC.setCorrectionRange(SS, TypoName);      return BestTC;    } @@ -4397,8 +4284,75 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,    // Record the failure's location if needed and return an empty correction. If    // this was an unqualified lookup and we believe the callback object did not    // filter out possible corrections, also cache the failure for the typo. -  return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure, -                          IsUnqualifiedLookup && !ValidatingCallback); +  return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure); +} + +/// \brief Try to "correct" a typo in the source code by finding +/// visible declarations whose names are similar to the name that was +/// present in the source code. +/// +/// \param TypoName the \c DeclarationNameInfo structure that contains +/// the name that was present in the source code along with its location. +/// +/// \param LookupKind the name-lookup criteria used to search for the name. +/// +/// \param S the scope in which name lookup occurs. +/// +/// \param SS the nested-name-specifier that precedes the name we're +/// looking for, if present. +/// +/// \param CCC A CorrectionCandidateCallback object that provides further +/// validation of typo correction candidates. It also provides flags for +/// determining the set of keywords permitted. +/// +/// \param TDG A TypoDiagnosticGenerator functor that will be used to print +/// diagnostics when the actual typo correction is attempted. +/// +/// \param TRC A TypoRecoveryCallback functor that will be used to build an +/// Expr from a typo correction candidate. +/// +/// \param MemberContext if non-NULL, the context in which to look for +/// a member access expression. +/// +/// \param EnteringContext whether we're entering the context described by +/// the nested-name-specifier SS. +/// +/// \param OPT when non-NULL, the search for visible declarations will +/// also walk the protocols in the qualified interfaces of \p OPT. +/// +/// \returns a new \c TypoExpr that will later be replaced in the AST with an +/// Expr representing the result of performing typo correction, or nullptr if +/// typo correction is not possible. If nullptr is returned, no diagnostics will +/// be emitted and it is the responsibility of the caller to emit any that are +/// needed. +TypoExpr *Sema::CorrectTypoDelayed( +    const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, +    Scope *S, CXXScopeSpec *SS, +    std::unique_ptr<CorrectionCandidateCallback> CCC, +    TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode, +    DeclContext *MemberContext, bool EnteringContext, +    const ObjCObjectPointerType *OPT) { +  assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback"); + +  TypoCorrection Empty; +  auto Consumer = makeTypoCorrectionConsumer( +      TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, +      EnteringContext, OPT, +      /*SearchModules=*/(Mode == CTK_ErrorRecovery) && getLangOpts().Modules && +          getLangOpts().ModulesSearchAll); + +  if (!Consumer || Consumer->empty()) +    return nullptr; + +  // Make sure the best edit distance (prior to adding any namespace qualifiers) +  // is not more that about a third of the length of the typo's identifier. +  unsigned ED = Consumer->getBestEditDistance(true); +  IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo(); +  if (ED > 0 && Typo->getName().size() / ED < 3) +    return nullptr; + +  ExprEvalContexts.back().NumTypos++; +  return createDelayedTypo(std::move(Consumer), std::move(TDG), std::move(TRC));  }  void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) { @@ -4425,7 +4379,8 @@ std::string TypoCorrection::getAsString(const LangOptions &LO) const {    return CorrectionName.getAsString();  } -bool CorrectionCandidateCallback::ValidateCandidate(const TypoCorrection &candidate) { +bool CorrectionCandidateCallback::ValidateCandidate( +    const TypoCorrection &candidate) {    if (!candidate.isResolved())      return true; @@ -4461,7 +4416,8 @@ FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,                                               MemberExpr *ME)      : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs),        CurContext(SemaRef.CurContext), MemberFn(ME) { -  WantTypeSpecifiers = SemaRef.getLangOpts().CPlusPlus; +  WantTypeSpecifiers = false; +  WantFunctionLikeCasts = SemaRef.getLangOpts().CPlusPlus && NumArgs == 1;    WantRemainingKeywords = false;  } @@ -4596,3 +4552,26 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction,      Diag(ChosenDecl->getLocation(), PrevNote)        << CorrectedQuotedStr << (ErrorRecovery ? FixItHint() : FixTypo);  } + +TypoExpr *Sema::createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, +                                  TypoDiagnosticGenerator TDG, +                                  TypoRecoveryCallback TRC) { +  assert(TCC && "createDelayedTypo requires a valid TypoCorrectionConsumer"); +  auto TE = new (Context) TypoExpr(Context.DependentTy); +  auto &State = DelayedTypos[TE]; +  State.Consumer = std::move(TCC); +  State.DiagHandler = std::move(TDG); +  State.RecoveryHandler = std::move(TRC); +  return TE; +} + +const Sema::TypoExprState &Sema::getTypoExprState(TypoExpr *TE) const { +  auto Entry = DelayedTypos.find(TE); +  assert(Entry != DelayedTypos.end() && +         "Failed to get the state for a TypoExpr!"); +  return Entry->second; +} + +void Sema::clearDelayedTypo(TypoExpr *TE) { +  DelayedTypos.erase(TE); +} diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 8eb806ba301a..72b6020351fa 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -116,9 +116,9 @@ static unsigned deduceWeakPropertyFromType(Sema &S, QualType T) {  static void  CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop,                               ObjCProtocolDecl *Proto, -                             llvm::SmallPtrSet<ObjCProtocolDecl *, 16> &Known) { +                             llvm::SmallPtrSetImpl<ObjCProtocolDecl *> &Known) {    // Have we seen this protocol before? -  if (!Known.insert(Proto)) +  if (!Known.insert(Proto).second)      return;    // Look for a property with the same name. @@ -1547,36 +1547,22 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl,        if (IMPDecl->getInstanceMethod(Prop->getSetterName()))          continue;      } -    // If property to be implemented in the super class, ignore. -    if (SuperPropMap[Prop->getIdentifier()]) { -      ObjCPropertyDecl *PropInSuperClass = SuperPropMap[Prop->getIdentifier()]; -      if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) && -          (PropInSuperClass->getPropertyAttributes() & -           ObjCPropertyDecl::OBJC_PR_readonly) && -          !IMPDecl->getInstanceMethod(Prop->getSetterName()) && -          !IDecl->HasUserDeclaredSetterMethod(Prop)) { -            Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property) -              << Prop->getIdentifier(); -            Diag(PropInSuperClass->getLocation(), diag::note_property_declare); -      } -      continue; -    }      if (ObjCPropertyImplDecl *PID =          IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) { -      if (PID->getPropertyDecl() != Prop) { -        Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property) -          << Prop->getIdentifier(); -        if (!PID->getLocation().isInvalid()) -          Diag(PID->getLocation(), diag::note_property_synthesize); -      } +      Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property) +        << Prop->getIdentifier(); +      if (!PID->getLocation().isInvalid()) +        Diag(PID->getLocation(), diag::note_property_synthesize);        continue;      } +    ObjCPropertyDecl *PropInSuperClass = SuperPropMap[Prop->getIdentifier()];      if (ObjCProtocolDecl *Proto =            dyn_cast<ObjCProtocolDecl>(Prop->getDeclContext())) {        // We won't auto-synthesize properties declared in protocols.        // Suppress the warning if class's superclass implements property's        // getter and implements property's setter (if readwrite property). -      if (!SuperClassImplementsProperty(IDecl, Prop)) { +      // Or, if property is going to be implemented in its super class. +      if (!SuperClassImplementsProperty(IDecl, Prop) && !PropInSuperClass) {          Diag(IMPDecl->getLocation(),               diag::warn_auto_synthesizing_protocol_property)            << Prop << Proto; @@ -1584,7 +1570,25 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl,        }        continue;      } - +    // If property to be implemented in the super class, ignore. +    if (PropInSuperClass) { +      if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) && +          (PropInSuperClass->getPropertyAttributes() & +           ObjCPropertyDecl::OBJC_PR_readonly) && +          !IMPDecl->getInstanceMethod(Prop->getSetterName()) && +          !IDecl->HasUserDeclaredSetterMethod(Prop)) { +        Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property) +        << Prop->getIdentifier(); +        Diag(PropInSuperClass->getLocation(), diag::note_property_declare); +      } +      else { +        Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass) +        << Prop->getIdentifier(); +        Diag(PropInSuperClass->getLocation(), diag::note_property_declare); +        Diag(IMPDecl->getLocation(), diag::note_while_in_implementation); +      } +      continue; +    }      // We use invalid SourceLocations for the synthesized ivars since they      // aren't really synthesized at a particular location; they just exist.      // Saying that they are located at the @implementation isn't really going diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 7f2af68e55d5..d72942a2ffec 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -13,6 +13,7 @@  //===----------------------------------------------------------------------===//  #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTMutationListener.h"  #include "clang/AST/Decl.h"  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclOpenMP.h" @@ -91,15 +92,17 @@ private:      DeclarationNameInfo DirectiveName;      Scope *CurScope;      SourceLocation ConstructLoc; +    bool OrderedRegion; +    SourceLocation InnerTeamsRegionLoc;      SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,                   Scope *CurScope, SourceLocation Loc)          : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),            Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), -          ConstructLoc(Loc) {} +          ConstructLoc(Loc), OrderedRegion(false), InnerTeamsRegionLoc() {}      SharingMapTy()          : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),            Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), -          ConstructLoc() {} +          ConstructLoc(), OrderedRegion(false), InnerTeamsRegionLoc() {}    };    typedef SmallVector<SharingMapTy, 64> StackTy; @@ -194,13 +197,42 @@ public:      return isOpenMPThreadPrivate(DVar.CKind);    } +  /// \brief Marks current region as ordered (it has an 'ordered' clause). +  void setOrderedRegion(bool IsOrdered = true) { +    Stack.back().OrderedRegion = IsOrdered; +  } +  /// \brief Returns true, if parent region is ordered (has associated +  /// 'ordered' clause), false - otherwise. +  bool isParentOrderedRegion() const { +    if (Stack.size() > 2) +      return Stack[Stack.size() - 2].OrderedRegion; +    return false; +  } + +  /// \brief Marks current target region as one with closely nested teams +  /// region. +  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { +    if (Stack.size() > 2) +      Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; +  } +  /// \brief Returns true, if current region has closely nested teams region. +  bool hasInnerTeamsRegion() const { +    return getInnerTeamsRegionLoc().isValid(); +  } +  /// \brief Returns location of the nested teams region (if any). +  SourceLocation getInnerTeamsRegionLoc() const { +    if (Stack.size() > 1) +      return Stack.back().InnerTeamsRegionLoc; +    return SourceLocation(); +  } +    Scope *getCurScope() const { return Stack.back().CurScope; }    Scope *getCurScope() { return Stack.back().CurScope; }    SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }  };  bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {    return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || -         DKind == OMPD_unknown; +         isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;  }  } // namespace @@ -213,7 +245,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,      //  File-scope or namespace-scope variables referenced in called routines      //  in the region are shared unless they appear in a threadprivate      //  directive. -    if (!D->isFunctionOrMethodVarDecl()) +    if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))        DVar.CKind = OMPC_shared;      // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced @@ -263,7 +295,8 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,      //  In a parallel construct, if no default clause is present, these      //  variables are shared.      DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; -    if (isOpenMPParallelDirective(DVar.DKind)) { +    if (isOpenMPParallelDirective(DVar.DKind) || +        isOpenMPTeamsDirective(DVar.DKind)) {        DVar.CKind = OMPC_shared;        return DVar;      } @@ -358,7 +391,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced    // in a Construct, C/C++, predetermined, p.1]    //  Variables appearing in threadprivate directives are threadprivate. -  if (D->getTLSKind() != VarDecl::TLS_None) { +  if (D->getTLSKind() != VarDecl::TLS_None || +      D->getStorageClass() == SC_Register) {      DVar.CKind = OMPC_threadprivate;      return DVar;    } @@ -380,8 +414,10 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {      StartI = std::next(StartI);    }    if (!isParallelOrTaskRegion(Kind)) { -    if (isOpenMPLocal(D, StartI) && D->isLocalVarDecl() && -        (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) { +    if (isOpenMPLocal(D, StartI) && +        ((D->isLocalVarDecl() && (D->getStorageClass() == SC_Auto || +                                  D->getStorageClass() == SC_None)) || +         isa<ParmVarDecl>(D))) {        DVar.CKind = OMPC_private;        return DVar;      } @@ -516,6 +552,19 @@ void Sema::InitDataSharingAttributesStack() {  #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) +bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { +  assert(LangOpts.OpenMP && "OpenMP is not allowed"); +  if (DSAStack->getCurrentDirective() != OMPD_unknown) { +    auto DVarPrivate = DSAStack->getTopDSA(VD, /*FromParent=*/false); +    if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) +      return true; +    DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), +                                   /*FromParent=*/false); +    return DVarPrivate.CKind != OMPC_unknown; +  } +  return false; +} +  void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }  void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, @@ -612,10 +661,9 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,    VarDecl *VD;    if (!Lookup.isSingleResult()) { -    VarDeclFilterCCC Validator(*this); -    if (TypoCorrection Corrected = -            CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, Validator, -                        CTK_ErrorRecovery)) { +    if (TypoCorrection Corrected = CorrectTypo( +            Id, LookupOrdinaryName, CurScope, nullptr, +            llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {        diagnoseTypo(Corrected,                     PDiag(Lookup.empty()                               ? diag::err_undeclared_var_use_suggest @@ -794,8 +842,10 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {      }      // Check if this is a TLS variable. -    if (VD->getTLSKind()) { -      Diag(ILoc, diag::err_omp_var_thread_local) << VD; +    if (VD->getTLSKind() != VarDecl::TLS_None || +        VD->getStorageClass() == SC_Register) { +      Diag(ILoc, diag::err_omp_var_thread_local) +          << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);        bool IsDecl =            VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;        Diag(VD->getLocation(), @@ -814,6 +864,10 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {      Vars.push_back(RefExpr);      DSAStack->addDSA(VD, DE, OMPC_threadprivate); +    VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( +        Context, SourceRange(Loc, Loc))); +    if (auto *ML = Context.getASTMutationListener()) +      ML->DeclarationMarkedOpenMPThreadPrivate(VD);    }    OMPThreadPrivateDecl *D = nullptr;    if (!Vars.empty()) { @@ -918,7 +972,8 @@ public:        DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),                                      [](OpenMPDirectiveKind K) -> bool {                                        return isOpenMPParallelDirective(K) || -                                             isOpenMPWorksharingDirective(K); +                                             isOpenMPWorksharingDirective(K) || +                                             isOpenMPTeamsDirective(K);                                      },                                      false);        if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { @@ -993,6 +1048,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {                               Params);      break;    } +  case OMPD_for_simd: { +    Sema::CapturedParamNameType Params[] = { +        std::make_pair(StringRef(), QualType()) // __context with shared vars +    }; +    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, +                             Params); +    break; +  }    case OMPD_sections: {      Sema::CapturedParamNameType Params[] = {          std::make_pair(StringRef(), QualType()) // __context with shared vars @@ -1045,6 +1108,18 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {                               Params);      break;    } +  case OMPD_parallel_for_simd: { +    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); +    QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); +    Sema::CapturedParamNameType Params[] = { +        std::make_pair(".global_tid.", KmpInt32PtrTy), +        std::make_pair(".bound_tid.", KmpInt32PtrTy), +        std::make_pair(StringRef(), QualType()) // __context with shared vars +    }; +    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, +                             Params); +    break; +  }    case OMPD_parallel_sections: {      Sema::CapturedParamNameType Params[] = {          std::make_pair(StringRef(), QualType()) // __context with shared vars @@ -1061,7 +1136,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {                               Params);      break;    } -  case OMPD_taskyield: { +  case OMPD_ordered: {      Sema::CapturedParamNameType Params[] = {          std::make_pair(StringRef(), QualType()) // __context with shared vars      }; @@ -1069,7 +1144,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {                               Params);      break;    } -  case OMPD_barrier: { +  case OMPD_atomic: {      Sema::CapturedParamNameType Params[] = {          std::make_pair(StringRef(), QualType()) // __context with shared vars      }; @@ -1077,7 +1152,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {                               Params);      break;    } -  case OMPD_taskwait: { +  case OMPD_target: {      Sema::CapturedParamNameType Params[] = {          std::make_pair(StringRef(), QualType()) // __context with shared vars      }; @@ -1085,8 +1160,12 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {                               Params);      break;    } -  case OMPD_flush: { +  case OMPD_teams: { +    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); +    QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);      Sema::CapturedParamNameType Params[] = { +        std::make_pair(".global_tid.", KmpInt32PtrTy), +        std::make_pair(".bound_tid.", KmpInt32PtrTy),          std::make_pair(StringRef(), QualType()) // __context with shared vars      };      ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, @@ -1094,6 +1173,10 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {      break;    }    case OMPD_threadprivate: +  case OMPD_taskyield: +  case OMPD_barrier: +  case OMPD_taskwait: +  case OMPD_flush:      llvm_unreachable("OpenMP Directive is not allowed");    case OMPD_unknown:      llvm_unreachable("Unknown OpenMP directive"); @@ -1110,6 +1193,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // +------------------+-----------------+------------------------------------+    // | parallel         | parallel        | *                                  |    // | parallel         | for             | *                                  | +  // | parallel         | for simd        | *                                  |    // | parallel         | master          | *                                  |    // | parallel         | critical        | *                                  |    // | parallel         | simd            | *                                  | @@ -1117,15 +1201,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | parallel         | section         | +                                  |    // | parallel         | single          | *                                  |    // | parallel         | parallel for    | *                                  | +  // | parallel         |parallel for simd| *                                  |    // | parallel         |parallel sections| *                                  |    // | parallel         | task            | *                                  |    // | parallel         | taskyield       | *                                  |    // | parallel         | barrier         | *                                  |    // | parallel         | taskwait        | *                                  |    // | parallel         | flush           | *                                  | +  // | parallel         | ordered         | +                                  | +  // | parallel         | atomic          | *                                  | +  // | parallel         | target          | *                                  | +  // | parallel         | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | for              | parallel        | *                                  |    // | for              | for             | +                                  | +  // | for              | for simd        | +                                  |    // | for              | master          | +                                  |    // | for              | critical        | *                                  |    // | for              | simd            | *                                  | @@ -1133,15 +1223,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | for              | section         | +                                  |    // | for              | single          | +                                  |    // | for              | parallel for    | *                                  | +  // | for              |parallel for simd| *                                  |    // | for              |parallel sections| *                                  |    // | for              | task            | *                                  |    // | for              | taskyield       | *                                  |    // | for              | barrier         | +                                  |    // | for              | taskwait        | *                                  |    // | for              | flush           | *                                  | +  // | for              | ordered         | * (if construct is ordered)        | +  // | for              | atomic          | *                                  | +  // | for              | target          | *                                  | +  // | for              | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | master           | parallel        | *                                  |    // | master           | for             | +                                  | +  // | master           | for simd        | +                                  |    // | master           | master          | *                                  |    // | master           | critical        | *                                  |    // | master           | simd            | *                                  | @@ -1149,30 +1245,42 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | master           | section         | +                                  |    // | master           | single          | +                                  |    // | master           | parallel for    | *                                  | +  // | master           |parallel for simd| *                                  |    // | master           |parallel sections| *                                  |    // | master           | task            | *                                  |    // | master           | taskyield       | *                                  |    // | master           | barrier         | +                                  |    // | master           | taskwait        | *                                  |    // | master           | flush           | *                                  | +  // | master           | ordered         | +                                  | +  // | master           | atomic          | *                                  | +  // | master           | target          | *                                  | +  // | master           | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | critical         | parallel        | *                                  |    // | critical         | for             | +                                  | +  // | critical         | for simd        | +                                  |    // | critical         | master          | *                                  | -  // | critical         | critical        | * (should have dirrerent names)    | +  // | critical         | critical        | * (should have different names)    |    // | critical         | simd            | *                                  |    // | critical         | sections        | +                                  |    // | critical         | section         | +                                  |    // | critical         | single          | +                                  |    // | critical         | parallel for    | *                                  | +  // | critical         |parallel for simd| *                                  |    // | critical         |parallel sections| *                                  |    // | critical         | task            | *                                  |    // | critical         | taskyield       | *                                  |    // | critical         | barrier         | +                                  |    // | critical         | taskwait        | *                                  | +  // | critical         | ordered         | +                                  | +  // | critical         | atomic          | *                                  | +  // | critical         | target          | *                                  | +  // | critical         | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | simd             | parallel        |                                    |    // | simd             | for             |                                    | +  // | simd             | for simd        |                                    |    // | simd             | master          |                                    |    // | simd             | critical        |                                    |    // | simd             | simd            |                                    | @@ -1180,15 +1288,65 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | simd             | section         |                                    |    // | simd             | single          |                                    |    // | simd             | parallel for    |                                    | +  // | simd             |parallel for simd|                                    |    // | simd             |parallel sections|                                    |    // | simd             | task            |                                    |    // | simd             | taskyield       |                                    |    // | simd             | barrier         |                                    |    // | simd             | taskwait        |                                    |    // | simd             | flush           |                                    | +  // | simd             | ordered         |                                    | +  // | simd             | atomic          |                                    | +  // | simd             | target          |                                    | +  // | simd             | teams           |                                    | +  // +------------------+-----------------+------------------------------------+ +  // | for simd         | parallel        |                                    | +  // | for simd         | for             |                                    | +  // | for simd         | for simd        |                                    | +  // | for simd         | master          |                                    | +  // | for simd         | critical        |                                    | +  // | for simd         | simd            |                                    | +  // | for simd         | sections        |                                    | +  // | for simd         | section         |                                    | +  // | for simd         | single          |                                    | +  // | for simd         | parallel for    |                                    | +  // | for simd         |parallel for simd|                                    | +  // | for simd         |parallel sections|                                    | +  // | for simd         | task            |                                    | +  // | for simd         | taskyield       |                                    | +  // | for simd         | barrier         |                                    | +  // | for simd         | taskwait        |                                    | +  // | for simd         | flush           |                                    | +  // | for simd         | ordered         |                                    | +  // | for simd         | atomic          |                                    | +  // | for simd         | target          |                                    | +  // | for simd         | teams           |                                    | +  // +------------------+-----------------+------------------------------------+ +  // | parallel for simd| parallel        |                                    | +  // | parallel for simd| for             |                                    | +  // | parallel for simd| for simd        |                                    | +  // | parallel for simd| master          |                                    | +  // | parallel for simd| critical        |                                    | +  // | parallel for simd| simd            |                                    | +  // | parallel for simd| sections        |                                    | +  // | parallel for simd| section         |                                    | +  // | parallel for simd| single          |                                    | +  // | parallel for simd| parallel for    |                                    | +  // | parallel for simd|parallel for simd|                                    | +  // | parallel for simd|parallel sections|                                    | +  // | parallel for simd| task            |                                    | +  // | parallel for simd| taskyield       |                                    | +  // | parallel for simd| barrier         |                                    | +  // | parallel for simd| taskwait        |                                    | +  // | parallel for simd| flush           |                                    | +  // | parallel for simd| ordered         |                                    | +  // | parallel for simd| atomic          |                                    | +  // | parallel for simd| target          |                                    | +  // | parallel for simd| teams           |                                    |    // +------------------+-----------------+------------------------------------+    // | sections         | parallel        | *                                  |    // | sections         | for             | +                                  | +  // | sections         | for simd        | +                                  |    // | sections         | master          | +                                  |    // | sections         | critical        | *                                  |    // | sections         | simd            | *                                  | @@ -1196,15 +1354,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | sections         | section         | *                                  |    // | sections         | single          | +                                  |    // | sections         | parallel for    | *                                  | +  // | sections         |parallel for simd| *                                  |    // | sections         |parallel sections| *                                  |    // | sections         | task            | *                                  |    // | sections         | taskyield       | *                                  |    // | sections         | barrier         | +                                  |    // | sections         | taskwait        | *                                  |    // | sections         | flush           | *                                  | +  // | sections         | ordered         | +                                  | +  // | sections         | atomic          | *                                  | +  // | sections         | target          | *                                  | +  // | sections         | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | section          | parallel        | *                                  |    // | section          | for             | +                                  | +  // | section          | for simd        | +                                  |    // | section          | master          | +                                  |    // | section          | critical        | *                                  |    // | section          | simd            | *                                  | @@ -1212,15 +1376,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | section          | section         | +                                  |    // | section          | single          | +                                  |    // | section          | parallel for    | *                                  | +  // | section          |parallel for simd| *                                  |    // | section          |parallel sections| *                                  |    // | section          | task            | *                                  |    // | section          | taskyield       | *                                  |    // | section          | barrier         | +                                  |    // | section          | taskwait        | *                                  |    // | section          | flush           | *                                  | +  // | section          | ordered         | +                                  | +  // | section          | atomic          | *                                  | +  // | section          | target          | *                                  | +  // | section          | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | single           | parallel        | *                                  |    // | single           | for             | +                                  | +  // | single           | for simd        | +                                  |    // | single           | master          | +                                  |    // | single           | critical        | *                                  |    // | single           | simd            | *                                  | @@ -1228,15 +1398,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | single           | section         | +                                  |    // | single           | single          | +                                  |    // | single           | parallel for    | *                                  | +  // | single           |parallel for simd| *                                  |    // | single           |parallel sections| *                                  |    // | single           | task            | *                                  |    // | single           | taskyield       | *                                  |    // | single           | barrier         | +                                  |    // | single           | taskwait        | *                                  |    // | single           | flush           | *                                  | +  // | single           | ordered         | +                                  | +  // | single           | atomic          | *                                  | +  // | single           | target          | *                                  | +  // | single           | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | parallel for     | parallel        | *                                  |    // | parallel for     | for             | +                                  | +  // | parallel for     | for simd        | +                                  |    // | parallel for     | master          | +                                  |    // | parallel for     | critical        | *                                  |    // | parallel for     | simd            | *                                  | @@ -1244,15 +1420,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | parallel for     | section         | +                                  |    // | parallel for     | single          | +                                  |    // | parallel for     | parallel for    | *                                  | +  // | parallel for     |parallel for simd| *                                  |    // | parallel for     |parallel sections| *                                  |    // | parallel for     | task            | *                                  |    // | parallel for     | taskyield       | *                                  |    // | parallel for     | barrier         | +                                  |    // | parallel for     | taskwait        | *                                  |    // | parallel for     | flush           | *                                  | +  // | parallel for     | ordered         | * (if construct is ordered)        | +  // | parallel for     | atomic          | *                                  | +  // | parallel for     | target          | *                                  | +  // | parallel for     | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | parallel sections| parallel        | *                                  |    // | parallel sections| for             | +                                  | +  // | parallel sections| for simd        | +                                  |    // | parallel sections| master          | +                                  |    // | parallel sections| critical        | +                                  |    // | parallel sections| simd            | *                                  | @@ -1260,15 +1442,21 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | parallel sections| section         | *                                  |    // | parallel sections| single          | +                                  |    // | parallel sections| parallel for    | *                                  | +  // | parallel sections|parallel for simd| *                                  |    // | parallel sections|parallel sections| *                                  |    // | parallel sections| task            | *                                  |    // | parallel sections| taskyield       | *                                  |    // | parallel sections| barrier         | +                                  |    // | parallel sections| taskwait        | *                                  |    // | parallel sections| flush           | *                                  | +  // | parallel sections| ordered         | +                                  | +  // | parallel sections| atomic          | *                                  | +  // | parallel sections| target          | *                                  | +  // | parallel sections| teams           | +                                  |    // +------------------+-----------------+------------------------------------+    // | task             | parallel        | *                                  |    // | task             | for             | +                                  | +  // | task             | for simd        | +                                  |    // | task             | master          | +                                  |    // | task             | critical        | *                                  |    // | task             | simd            | *                                  | @@ -1276,24 +1464,128 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,    // | task             | section         | +                                  |    // | task             | single          | +                                  |    // | task             | parallel for    | *                                  | +  // | task             |parallel for simd| *                                  |    // | task             |parallel sections| *                                  |    // | task             | task            | *                                  |    // | task             | taskyield       | *                                  |    // | task             | barrier         | +                                  |    // | task             | taskwait        | *                                  |    // | task             | flush           | *                                  | +  // | task             | ordered         | +                                  | +  // | task             | atomic          | *                                  | +  // | task             | target          | *                                  | +  // | task             | teams           | +                                  | +  // +------------------+-----------------+------------------------------------+ +  // | ordered          | parallel        | *                                  | +  // | ordered          | for             | +                                  | +  // | ordered          | for simd        | +                                  | +  // | ordered          | master          | *                                  | +  // | ordered          | critical        | *                                  | +  // | ordered          | simd            | *                                  | +  // | ordered          | sections        | +                                  | +  // | ordered          | section         | +                                  | +  // | ordered          | single          | +                                  | +  // | ordered          | parallel for    | *                                  | +  // | ordered          |parallel for simd| *                                  | +  // | ordered          |parallel sections| *                                  | +  // | ordered          | task            | *                                  | +  // | ordered          | taskyield       | *                                  | +  // | ordered          | barrier         | +                                  | +  // | ordered          | taskwait        | *                                  | +  // | ordered          | flush           | *                                  | +  // | ordered          | ordered         | +                                  | +  // | ordered          | atomic          | *                                  | +  // | ordered          | target          | *                                  | +  // | ordered          | teams           | +                                  | +  // +------------------+-----------------+------------------------------------+ +  // | atomic           | parallel        |                                    | +  // | atomic           | for             |                                    | +  // | atomic           | for simd        |                                    | +  // | atomic           | master          |                                    | +  // | atomic           | critical        |                                    | +  // | atomic           | simd            |                                    | +  // | atomic           | sections        |                                    | +  // | atomic           | section         |                                    | +  // | atomic           | single          |                                    | +  // | atomic           | parallel for    |                                    | +  // | atomic           |parallel for simd|                                    | +  // | atomic           |parallel sections|                                    | +  // | atomic           | task            |                                    | +  // | atomic           | taskyield       |                                    | +  // | atomic           | barrier         |                                    | +  // | atomic           | taskwait        |                                    | +  // | atomic           | flush           |                                    | +  // | atomic           | ordered         |                                    | +  // | atomic           | atomic          |                                    | +  // | atomic           | target          |                                    | +  // | atomic           | teams           |                                    | +  // +------------------+-----------------+------------------------------------+ +  // | target           | parallel        | *                                  | +  // | target           | for             | *                                  | +  // | target           | for simd        | *                                  | +  // | target           | master          | *                                  | +  // | target           | critical        | *                                  | +  // | target           | simd            | *                                  | +  // | target           | sections        | *                                  | +  // | target           | section         | *                                  | +  // | target           | single          | *                                  | +  // | target           | parallel for    | *                                  | +  // | target           |parallel for simd| *                                  | +  // | target           |parallel sections| *                                  | +  // | target           | task            | *                                  | +  // | target           | taskyield       | *                                  | +  // | target           | barrier         | *                                  | +  // | target           | taskwait        | *                                  | +  // | target           | flush           | *                                  | +  // | target           | ordered         | *                                  | +  // | target           | atomic          | *                                  | +  // | target           | target          | *                                  | +  // | target           | teams           | *                                  | +  // +------------------+-----------------+------------------------------------+ +  // | teams            | parallel        | *                                  | +  // | teams            | for             | +                                  | +  // | teams            | for simd        | +                                  | +  // | teams            | master          | +                                  | +  // | teams            | critical        | +                                  | +  // | teams            | simd            | +                                  | +  // | teams            | sections        | +                                  | +  // | teams            | section         | +                                  | +  // | teams            | single          | +                                  | +  // | teams            | parallel for    | *                                  | +  // | teams            |parallel for simd| *                                  | +  // | teams            |parallel sections| *                                  | +  // | teams            | task            | +                                  | +  // | teams            | taskyield       | +                                  | +  // | teams            | barrier         | +                                  | +  // | teams            | taskwait        | +                                  | +  // | teams            | flush           | +                                  | +  // | teams            | ordered         | +                                  | +  // | teams            | atomic          | +                                  | +  // | teams            | target          | +                                  | +  // | teams            | teams           | +                                  |    // +------------------+-----------------+------------------------------------+    if (Stack->getCurScope()) {      auto ParentRegion = Stack->getParentDirective();      bool NestingProhibited = false;      bool CloseNesting = true; -    bool ShouldBeInParallelRegion = false; +    enum { +      NoRecommend, +      ShouldBeInParallelRegion, +      ShouldBeInOrderedRegion, +      ShouldBeInTargetRegion +    } Recommend = NoRecommend;      if (isOpenMPSimdDirective(ParentRegion)) {        // OpenMP [2.16, Nesting of Regions]        // OpenMP constructs may not be nested inside a simd region.        SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);        return true;      } +    if (ParentRegion == OMPD_atomic) { +      // OpenMP [2.16, Nesting of Regions] +      // OpenMP constructs may not be nested inside an atomic region. +      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); +      return true; +    }      if (CurrentRegion == OMPD_section) {        // OpenMP [2.7.2, sections Construct, Restrictions]        // Orphaned section directives are prohibited. That is, the section @@ -1308,10 +1600,14 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,        }        return false;      } +    // Allow some constructs to be orphaned (they could be used in functions, +    // called from OpenMP regions with the required preconditions). +    if (ParentRegion == OMPD_unknown) +      return false;      if (CurrentRegion == OMPD_master) {        // OpenMP [2.16, Nesting of Regions]        // A master region may not be closely nested inside a worksharing, -      // atomic (TODO), or explicit task region. +      // atomic, or explicit task region.        NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||                            ParentRegion == OMPD_task;      } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { @@ -1346,30 +1642,52 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,      } else if (CurrentRegion == OMPD_barrier) {        // OpenMP [2.16, Nesting of Regions]        // A barrier region may not be closely nested inside a worksharing, -      // explicit task, critical, ordered(TODO), atomic(TODO), or master -      // region. -      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || -                          ParentRegion == OMPD_task || -                          ParentRegion == OMPD_master || -                          ParentRegion == OMPD_critical; +      // explicit task, critical, ordered, atomic, or master region. +      NestingProhibited = +          isOpenMPWorksharingDirective(ParentRegion) || +          ParentRegion == OMPD_task || ParentRegion == OMPD_master || +          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;      } else if (isOpenMPWorksharingDirective(CurrentRegion) && -               !isOpenMPParallelDirective(CurrentRegion) && -               !isOpenMPSimdDirective(CurrentRegion)) { +               !isOpenMPParallelDirective(CurrentRegion)) {        // OpenMP [2.16, Nesting of Regions]        // A worksharing region may not be closely nested inside a worksharing,        // explicit task, critical, ordered, atomic, or master region. -      // TODO -      NestingProhibited = (isOpenMPWorksharingDirective(ParentRegion) && -                           !isOpenMPSimdDirective(ParentRegion)) || +      NestingProhibited = +          isOpenMPWorksharingDirective(ParentRegion) || +          ParentRegion == OMPD_task || ParentRegion == OMPD_master || +          ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; +      Recommend = ShouldBeInParallelRegion; +    } else if (CurrentRegion == OMPD_ordered) { +      // OpenMP [2.16, Nesting of Regions] +      // An ordered region may not be closely nested inside a critical, +      // atomic, or explicit task region. +      // An ordered region must be closely nested inside a loop region (or +      // parallel loop region) with an ordered clause. +      NestingProhibited = ParentRegion == OMPD_critical ||                            ParentRegion == OMPD_task || -                          ParentRegion == OMPD_master || -                          ParentRegion == OMPD_critical; -      ShouldBeInParallelRegion = true; +                          !Stack->isParentOrderedRegion(); +      Recommend = ShouldBeInOrderedRegion; +    } else if (isOpenMPTeamsDirective(CurrentRegion)) { +      // OpenMP [2.16, Nesting of Regions] +      // If specified, a teams construct must be contained within a target +      // construct. +      NestingProhibited = ParentRegion != OMPD_target; +      Recommend = ShouldBeInTargetRegion; +      Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); +    } +    if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { +      // OpenMP [2.16, Nesting of Regions] +      // distribute, parallel, parallel sections, parallel workshare, and the +      // parallel loop and parallel loop SIMD constructs are the only OpenMP +      // constructs that can be closely nested in the teams region. +      // TODO: add distribute directive. +      NestingProhibited = !isOpenMPParallelDirective(CurrentRegion); +      Recommend = ShouldBeInParallelRegion;      }      if (NestingProhibited) {        SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) -          << CloseNesting << getOpenMPDirectiveName(ParentRegion) -          << ShouldBeInParallelRegion << getOpenMPDirectiveName(CurrentRegion); +          << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend +          << getOpenMPDirectiveName(CurrentRegion);        return true;      }    } @@ -1426,6 +1744,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,      Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,                                    VarsWithInheritedDSA);      break; +  case OMPD_for_simd: +    Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, +                                      EndLoc, VarsWithInheritedDSA); +    break;    case OMPD_sections:      Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,                                         EndLoc); @@ -1453,6 +1775,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,      Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,                                            EndLoc, VarsWithInheritedDSA);      break; +  case OMPD_parallel_for_simd: +    Res = ActOnOpenMPParallelForSimdDirective( +        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); +    break;    case OMPD_parallel_sections:      Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,                                                 StartLoc, EndLoc); @@ -1487,6 +1813,23 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,             "No associated statement allowed for 'omp flush' directive");      Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);      break; +  case OMPD_ordered: +    assert(ClausesWithImplicit.empty() && +           "No clauses are allowed for 'omp ordered' directive"); +    Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc); +    break; +  case OMPD_atomic: +    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, +                                     EndLoc); +    break; +  case OMPD_teams: +    Res = +        ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); +    break; +  case OMPD_target: +    Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, +                                     EndLoc); +    break;    case OMPD_threadprivate:      llvm_unreachable("OpenMP Directive is not allowed");    case OMPD_unknown: @@ -1535,10 +1878,16 @@ class OpenMPIterationSpaceChecker {    SourceLocation DefaultLoc;    /// \brief A location for diagnostics (when increment is not compatible).    SourceLocation ConditionLoc; +  /// \brief A source location for referring to loop init later. +  SourceRange InitSrcRange;    /// \brief A source location for referring to condition later.    SourceRange ConditionSrcRange; +  /// \brief A source location for referring to increment later. +  SourceRange IncrementSrcRange;    /// \brief Loop variable.    VarDecl *Var; +  /// \brief Reference to loop variable. +  DeclRefExpr *VarRef;    /// \brief Lower bound (initializer for the var).    Expr *LB;    /// \brief Upper bound. @@ -1559,9 +1908,10 @@ class OpenMPIterationSpaceChecker {  public:    OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)        : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc), -        ConditionSrcRange(SourceRange()), Var(nullptr), LB(nullptr), -        UB(nullptr), Step(nullptr), TestIsLessOp(false), TestIsStrictOp(false), -        SubtractStep(false) {} +        InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()), +        IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr), +        LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false), +        TestIsStrictOp(false), SubtractStep(false) {}    /// \brief Check init-expr for canonical loop form and save loop counter    /// variable - #Var and its initialization value - #LB.    bool CheckInit(Stmt *S); @@ -1573,6 +1923,24 @@ public:    bool CheckInc(Expr *S);    /// \brief Return the loop counter variable.    VarDecl *GetLoopVar() const { return Var; } +  /// \brief Return the reference expression to loop counter variable. +  DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; } +  /// \brief Source range of the loop init. +  SourceRange GetInitSrcRange() const { return InitSrcRange; } +  /// \brief Source range of the loop condition. +  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } +  /// \brief Source range of the loop increment. +  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } +  /// \brief True if the step should be subtracted. +  bool ShouldSubtractStep() const { return SubtractStep; } +  /// \brief Build the expression to calculate the number of iterations. +  Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; +  /// \brief Build reference expression to the counter be used for codegen. +  Expr *BuildCounterVar() const; +  /// \brief Build initization of the counter be used for codegen. +  Expr *BuildCounterInit() const; +  /// \brief Build step of the counter be used for codegen. +  Expr *BuildCounterStep() const;    /// \brief Return true if any expression is dependent.    bool Dependent() const; @@ -1581,7 +1949,7 @@ private:    /// expression.    bool CheckIncRHS(Expr *RHS);    /// \brief Helper to set loop counter variable and its initializer. -  bool SetVarAndLB(VarDecl *NewVar, Expr *NewLB); +  bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB);    /// \brief Helper to set upper bound.    bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR,               const SourceLocation &SL); @@ -1598,13 +1966,16 @@ bool OpenMPIterationSpaceChecker::Dependent() const {           (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());  } -bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, Expr *NewLB) { +bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, +                                              DeclRefExpr *NewVarRefExpr, +                                              Expr *NewLB) {    // State consistency checking to ensure correct usage. -  assert(Var == nullptr && LB == nullptr && UB == nullptr && Step == nullptr && -         !TestIsLessOp && !TestIsStrictOp); +  assert(Var == nullptr && LB == nullptr && VarRef == nullptr && +         UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);    if (!NewVar || !NewLB)      return true;    Var = NewVar; +  VarRef = NewVarRefExpr;    LB = NewLB;    return false;  } @@ -1655,10 +2026,12 @@ bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {      bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();      bool IsConstNeg =          IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); +    bool IsConstPos = +        IsConstant && Result.isSigned() && (Subtract == Result.isNegative());      bool IsConstZero = IsConstant && !Result.getBoolValue();      if (UB && (IsConstZero ||                 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) -                             : (!IsConstNeg || (IsUnsigned && !Subtract))))) { +                             : (IsConstPos || (IsUnsigned && !Subtract))))) {        SemaRef.Diag(NewStep->getExprLoc(),                     diag::err_omp_loop_incr_not_compatible)            << Var << TestIsLessOp << NewStep->getSourceRange(); @@ -1667,6 +2040,11 @@ bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {            << TestIsLessOp << ConditionSrcRange;        return true;      } +    if (TestIsLessOp == Subtract) { +      NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, +                                             NewStep).get(); +      Subtract = !Subtract; +    }    }    Step = NewStep; @@ -1687,12 +2065,14 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S) {      SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);      return true;    } +  InitSrcRange = S->getSourceRange();    if (Expr *E = dyn_cast<Expr>(S))      S = E->IgnoreParens();    if (auto BO = dyn_cast<BinaryOperator>(S)) {      if (BO->getOpcode() == BO_Assign)        if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) -        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), BO->getLHS()); +        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, +                           BO->getRHS());    } else if (auto DS = dyn_cast<DeclStmt>(S)) {      if (DS->isSingleDecl()) {        if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { @@ -1702,14 +2082,15 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S) {              SemaRef.Diag(S->getLocStart(),                           diag::ext_omp_loop_not_canonical_init)                  << S->getSourceRange(); -          return SetVarAndLB(Var, Var->getInit()); +          return SetVarAndLB(Var, nullptr, Var->getInit());          }        }      }    } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))      if (CE->getOperator() == OO_Equal)        if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0))) -        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), CE->getArg(1)); +        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, +                           CE->getArg(1));    SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)        << S->getSourceRange(); @@ -1833,6 +2214,7 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {      SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;      return true;    } +  IncrementSrcRange = S->getSourceRange();    S = S->IgnoreParens();    if (auto UO = dyn_cast<UnaryOperator>(S)) {      if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var) @@ -1882,6 +2264,115 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {        << S->getSourceRange() << Var;    return true;  } + +/// \brief Build the expression to calculate the number of iterations. +Expr * +OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, +                                                const bool LimitedType) const { +  ExprResult Diff; +  if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || +      SemaRef.getLangOpts().CPlusPlus) { +    // Upper - Lower +    Expr *Upper = TestIsLessOp ? UB : LB; +    Expr *Lower = TestIsLessOp ? LB : UB; + +    Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); + +    if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) { +      // BuildBinOp already emitted error, this one is to point user to upper +      // and lower bound, and to tell what is passed to 'operator-'. +      SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) +          << Upper->getSourceRange() << Lower->getSourceRange(); +      return nullptr; +    } +  } + +  if (!Diff.isUsable()) +    return nullptr; + +  // Upper - Lower [- 1] +  if (TestIsStrictOp) +    Diff = SemaRef.BuildBinOp( +        S, DefaultLoc, BO_Sub, Diff.get(), +        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); +  if (!Diff.isUsable()) +    return nullptr; + +  // Upper - Lower [- 1] + Step +  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), +                            Step->IgnoreImplicit()); +  if (!Diff.isUsable()) +    return nullptr; + +  // Parentheses (for dumping/debugging purposes only). +  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); +  if (!Diff.isUsable()) +    return nullptr; + +  // (Upper - Lower [- 1] + Step) / Step +  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), +                            Step->IgnoreImplicit()); +  if (!Diff.isUsable()) +    return nullptr; + +  // OpenMP runtime requires 32-bit or 64-bit loop variables. +  if (LimitedType) { +    auto &C = SemaRef.Context; +    QualType Type = Diff.get()->getType(); +    unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; +    if (NewSize != C.getTypeSize(Type)) { +      if (NewSize < C.getTypeSize(Type)) { +        assert(NewSize == 64 && "incorrect loop var size"); +        SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) +            << InitSrcRange << ConditionSrcRange; +      } +      QualType NewType = C.getIntTypeForBitwidth( +          NewSize, Type->hasSignedIntegerRepresentation()); +      Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, +                                               Sema::AA_Converting, true); +      if (!Diff.isUsable()) +        return nullptr; +    } +  } + +  return Diff.get(); +} + +/// \brief Build reference expression to the counter be used for codegen. +Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { +  return DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), +                             GetIncrementSrcRange().getBegin(), Var, false, +                             DefaultLoc, Var->getType(), VK_LValue); +} + +/// \brief Build initization of the counter be used for codegen. +Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } + +/// \brief Build step of the counter be used for codegen. +Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } + +/// \brief Iteration space of a single for loop. +struct LoopIterationSpace { +  /// \brief This expression calculates the number of iterations in the loop. +  /// It is always possible to calculate it before starting the loop. +  Expr *NumIterations; +  /// \brief The loop counter variable. +  Expr *CounterVar; +  /// \brief This is initializer for the initial value of #CounterVar. +  Expr *CounterInit; +  /// \brief This is step for the #CounterVar used to generate its update: +  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. +  Expr *CounterStep; +  /// \brief Should step be subtracted? +  bool Subtract; +  /// \brief Source range of the loop init. +  SourceRange InitSrcRange; +  /// \brief Source range of the loop condition. +  SourceRange CondSrcRange; +  /// \brief Source range of the loop increment. +  SourceRange IncSrcRange; +}; +  } // namespace  /// \brief Called on a for stmt to check and extract its iteration space @@ -1890,7 +2381,8 @@ static bool CheckOpenMPIterationSpace(      OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,      unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,      Expr *NestedLoopCountExpr, -    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { +    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, +    LoopIterationSpace &ResultIterSpace) {    // OpenMP [2.6, Canonical Loop Form]    //   for (init-expr; test-expr; incr-expr) structured-block    auto For = dyn_cast_or_null<ForStmt>(S); @@ -1943,8 +2435,7 @@ static bool CheckOpenMPIterationSpace(    // that is the increment of the associated for-loop.    // Exclude loop var from the list of variables with implicitly defined data    // sharing attributes. -  while (VarsWithImplicitDSA.count(Var) > 0) -    VarsWithImplicitDSA.erase(Var); +  VarsWithImplicitDSA.erase(Var);    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in    // a Construct, C/C++]. @@ -1954,25 +2445,40 @@ static bool CheckOpenMPIterationSpace(    // The loop iteration variable(s) in the associated for-loop(s) of a for or    // parallel for construct may be listed in a private or lastprivate clause.    DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false); +  auto LoopVarRefExpr = ISC.GetLoopVarRefExpr(); +  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is +  // declared in the loop and it is predetermined as a private.    auto PredeterminedCKind =        isOpenMPSimdDirective(DKind)            ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)            : OMPC_private;    if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&          DVar.CKind != PredeterminedCKind) || -       (isOpenMPWorksharingDirective(DKind) && DVar.CKind != OMPC_unknown && -        DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && +       (isOpenMPWorksharingDirective(DKind) && !isOpenMPSimdDirective(DKind) && +        DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && +        DVar.CKind != OMPC_lastprivate)) &&        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {      SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)          << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)          << getOpenMPClauseName(PredeterminedCKind);      ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true);      HasErrors = true; -  } else { +  } else if (LoopVarRefExpr != nullptr) {      // Make the loop iteration variable private (for worksharing constructs),      // linear (for simd directives with the only one associated loop) or      // lastprivate (for simd directives with several collapsed loops). -    DSA.addDSA(Var, nullptr, PredeterminedCKind); +    // FIXME: the next check and error message must be removed once the +    // capturing of global variables in loops is fixed. +    if (DVar.CKind == OMPC_unknown) +      DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(), +                        /*FromParent=*/false); +    if (!Var->hasLocalStorage() && DVar.CKind == OMPC_unknown) { +      SemaRef.Diag(Init->getLocStart(), diag::err_omp_global_loop_var_dsa) +          << getOpenMPClauseName(PredeterminedCKind) +          << getOpenMPDirectiveName(DKind); +      HasErrors = true; +    } else +      DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);    }    assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); @@ -1983,35 +2489,97 @@ static bool CheckOpenMPIterationSpace(    // Check incr-expr.    HasErrors |= ISC.CheckInc(For->getInc()); -  if (ISC.Dependent()) +  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)      return HasErrors; -  // FIXME: Build loop's iteration space representation. +  // Build the loop's iteration space representation. +  ResultIterSpace.NumIterations = ISC.BuildNumIterations( +      DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); +  ResultIterSpace.CounterVar = ISC.BuildCounterVar(); +  ResultIterSpace.CounterInit = ISC.BuildCounterInit(); +  ResultIterSpace.CounterStep = ISC.BuildCounterStep(); +  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); +  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); +  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); +  ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); + +  HasErrors |= (ResultIterSpace.NumIterations == nullptr || +                ResultIterSpace.CounterVar == nullptr || +                ResultIterSpace.CounterInit == nullptr || +                ResultIterSpace.CounterStep == nullptr); +    return HasErrors;  } -/// \brief A helper routine to skip no-op (attributed, compound) stmts get the -/// next nested for loop. If \a IgnoreCaptured is true, it skips captured stmt -/// to get the first for loop. -static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) { -  if (IgnoreCaptured) -    if (auto CapS = dyn_cast_or_null<CapturedStmt>(S)) -      S = CapS->getCapturedStmt(); -  // OpenMP [2.8.1, simd construct, Restrictions] -  // All loops associated with the construct must be perfectly nested; that is, -  // there must be no intervening code nor any OpenMP directive between any two -  // loops. -  while (true) { -    if (auto AS = dyn_cast_or_null<AttributedStmt>(S)) -      S = AS->getSubStmt(); -    else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) { -      if (CS->size() != 1) -        break; -      S = CS->body_back(); -    } else -      break; -  } -  return S; +/// \brief Build a variable declaration for OpenMP loop iteration variable. +static VarDecl *BuildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, +                             StringRef Name) { +  DeclContext *DC = SemaRef.CurContext; +  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); +  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); +  VarDecl *Decl = +      VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); +  Decl->setImplicit(); +  return Decl; +} + +/// \brief Build 'VarRef = Start + Iter * Step'. +static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, +                                     SourceLocation Loc, ExprResult VarRef, +                                     ExprResult Start, ExprResult Iter, +                                     ExprResult Step, bool Subtract) { +  // Add parentheses (for debugging purposes only). +  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); +  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || +      !Step.isUsable()) +    return ExprError(); + +  ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), +                                         Step.get()->IgnoreImplicit()); +  if (!Update.isUsable()) +    return ExprError(); + +  // Build 'VarRef = Start + Iter * Step'. +  Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), +                              Start.get()->IgnoreImplicit(), Update.get()); +  if (!Update.isUsable()) +    return ExprError(); + +  Update = SemaRef.PerformImplicitConversion( +      Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); +  if (!Update.isUsable()) +    return ExprError(); + +  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); +  return Update; +} + +/// \brief Convert integer expression \a E to make it have at least \a Bits +/// bits. +static ExprResult WidenIterationCount(unsigned Bits, Expr *E, +                                      Sema &SemaRef) { +  if (E == nullptr) +    return ExprError(); +  auto &C = SemaRef.Context; +  QualType OldType = E->getType(); +  unsigned HasBits = C.getTypeSize(OldType); +  if (HasBits >= Bits) +    return ExprResult(E); +  // OK to convert to signed, because new type has more bits than old. +  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); +  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, +                                           true); +} + +/// \brief Check if the given expression \a E is a constant integer that fits +/// into \a Bits bits. +static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { +  if (E == nullptr) +    return false; +  llvm::APSInt Result; +  if (E->isIntegerConstantExpr(Result, SemaRef.Context)) +    return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); +  return false;  }  /// \brief Called on a for stmt to check itself and nested loops (if any). @@ -2020,7 +2588,8 @@ static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) {  static unsigned  CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,                  Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, -                llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { +                llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, +                OMPLoopDirective::HelperExprs &Built) {    unsigned NestedLoopCount = 1;    if (NestedLoopCountExpr) {      // Found 'collapse' clause - calculate collapse number. @@ -2030,18 +2599,336 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,    }    // This is helper routine for loop directives (e.g., 'for', 'simd',    // 'for simd', etc.). -  Stmt *CurStmt = IgnoreContainerStmts(AStmt, true); +  SmallVector<LoopIterationSpace, 4> IterSpaces; +  IterSpaces.resize(NestedLoopCount); +  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);    for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {      if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,                                    NestedLoopCount, NestedLoopCountExpr, -                                  VarsWithImplicitDSA)) +                                  VarsWithImplicitDSA, IterSpaces[Cnt]))        return 0;      // Move on to the next nested for loop, or to the loop body. -    CurStmt = IgnoreContainerStmts(cast<ForStmt>(CurStmt)->getBody(), false); +    // OpenMP [2.8.1, simd construct, Restrictions] +    // All loops associated with the construct must be perfectly nested; that +    // is, there must be no intervening code nor any OpenMP directive between +    // any two loops. +    CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); +  } + +  Built.clear(/* size */ NestedLoopCount); + +  if (SemaRef.CurContext->isDependentContext()) +    return NestedLoopCount; + +  // An example of what is generated for the following code: +  // +  //   #pragma omp simd collapse(2) +  //   for (i = 0; i < NI; ++i) +  //     for (j = J0; j < NJ; j+=2) { +  //     <loop body> +  //   } +  // +  // We generate the code below. +  // Note: the loop body may be outlined in CodeGen. +  // Note: some counters may be C++ classes, operator- is used to find number of +  // iterations and operator+= to calculate counter value. +  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 +  // or i64 is currently supported). +  // +  //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) +  //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { +  //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2); +  //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; +  //     // similar updates for vars in clauses (e.g. 'linear') +  //     <loop body (using local i and j)> +  //   } +  //   i = NI; // assign final values of counters +  //   j = NJ; +  // + +  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are +  // the iteration counts of the collapsed for loops. +  auto N0 = IterSpaces[0].NumIterations; +  ExprResult LastIteration32 = WidenIterationCount(32 /* Bits */, N0, SemaRef); +  ExprResult LastIteration64 = WidenIterationCount(64 /* Bits */, N0, SemaRef); + +  if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) +    return NestedLoopCount; + +  auto &C = SemaRef.Context; +  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; + +  Scope *CurScope = DSA.getCurScope(); +  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { +    auto N = IterSpaces[Cnt].NumIterations; +    AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; +    if (LastIteration32.isUsable()) +      LastIteration32 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, +                                           LastIteration32.get(), N); +    if (LastIteration64.isUsable()) +      LastIteration64 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, +                                           LastIteration64.get(), N); +  } + +  // Choose either the 32-bit or 64-bit version. +  ExprResult LastIteration = LastIteration64; +  if (LastIteration32.isUsable() && +      C.getTypeSize(LastIteration32.get()->getType()) == 32 && +      (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || +       FitsInto( +           32 /* Bits */, +           LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), +           LastIteration64.get(), SemaRef))) +    LastIteration = LastIteration32; + +  if (!LastIteration.isUsable()) +    return 0; + +  // Save the number of iterations. +  ExprResult NumIterations = LastIteration; +  { +    LastIteration = SemaRef.BuildBinOp( +        CurScope, SourceLocation(), BO_Sub, LastIteration.get(), +        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); +    if (!LastIteration.isUsable()) +      return 0; +  } + +  // Calculate the last iteration number beforehand instead of doing this on +  // each iteration. Do not do this if the number of iterations may be kfold-ed. +  llvm::APSInt Result; +  bool IsConstant = +      LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); +  ExprResult CalcLastIteration; +  if (!IsConstant) { +    SourceLocation SaveLoc; +    VarDecl *SaveVar = +        BuildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), +                     ".omp.last.iteration"); +    ExprResult SaveRef = SemaRef.BuildDeclRefExpr( +        SaveVar, LastIteration.get()->getType(), VK_LValue, SaveLoc); +    CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, +                                           SaveRef.get(), LastIteration.get()); +    LastIteration = SaveRef; + +    // Prepare SaveRef + 1. +    NumIterations = SemaRef.BuildBinOp( +        CurScope, SaveLoc, BO_Add, SaveRef.get(), +        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); +    if (!NumIterations.isUsable()) +      return 0; +  } + +  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); + +  // Precondition tests if there is at least one iteration (LastIteration > 0). +  ExprResult PreCond = SemaRef.BuildBinOp( +      CurScope, InitLoc, BO_GT, LastIteration.get(), +      SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get()); + +  QualType VType = LastIteration.get()->getType(); +  // Build variables passed into runtime, nesessary for worksharing directives. +  ExprResult LB, UB, IL, ST, EUB; +  if (isOpenMPWorksharingDirective(DKind)) { +    // Lower bound variable, initialized with zero. +    VarDecl *LBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); +    LB = SemaRef.BuildDeclRefExpr(LBDecl, VType, VK_LValue, InitLoc); +    SemaRef.AddInitializerToDecl( +        LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), +        /*DirectInit*/ false, /*TypeMayContainAuto*/ false); + +    // Upper bound variable, initialized with last iteration number. +    VarDecl *UBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); +    UB = SemaRef.BuildDeclRefExpr(UBDecl, VType, VK_LValue, InitLoc); +    SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), +                                 /*DirectInit*/ false, +                                 /*TypeMayContainAuto*/ false); + +    // A 32-bit variable-flag where runtime returns 1 for the last iteration. +    // This will be used to implement clause 'lastprivate'. +    QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); +    VarDecl *ILDecl = BuildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); +    IL = SemaRef.BuildDeclRefExpr(ILDecl, Int32Ty, VK_LValue, InitLoc); +    SemaRef.AddInitializerToDecl( +        ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), +        /*DirectInit*/ false, /*TypeMayContainAuto*/ false); + +    // Stride variable returned by runtime (we initialize it to 1 by default). +    VarDecl *STDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); +    ST = SemaRef.BuildDeclRefExpr(STDecl, VType, VK_LValue, InitLoc); +    SemaRef.AddInitializerToDecl( +        STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), +        /*DirectInit*/ false, /*TypeMayContainAuto*/ false); + +    // Build expression: UB = min(UB, LastIteration) +    // It is nesessary for CodeGen of directives with static scheduling. +    ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, +                                                UB.get(), LastIteration.get()); +    ExprResult CondOp = SemaRef.ActOnConditionalOp( +        InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); +    EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), +                             CondOp.get()); +    EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); +  } + +  // Build the iteration variable and its initialization before loop. +  ExprResult IV; +  ExprResult Init; +  { +    VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); +    IV = SemaRef.BuildDeclRefExpr(IVDecl, VType, VK_LValue, InitLoc); +    Expr *RHS = isOpenMPWorksharingDirective(DKind) +                    ? LB.get() +                    : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); +    Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); +    Init = SemaRef.ActOnFinishFullExpr(Init.get());    } -  // FIXME: Build resulting iteration space for IR generation (collapsing -  // iteration spaces when loop count > 1 ('collapse' clause)). +  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. +  SourceLocation CondLoc; +  ExprResult Cond = +      isOpenMPWorksharingDirective(DKind) +          ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) +          : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), +                               NumIterations.get()); +  // Loop condition with 1 iteration separated (IV < LastIteration) +  ExprResult SeparatedCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, +                                                IV.get(), LastIteration.get()); + +  // Loop increment (IV = IV + 1) +  SourceLocation IncLoc; +  ExprResult Inc = +      SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), +                         SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); +  if (!Inc.isUsable()) +    return 0; +  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); +  Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); +  if (!Inc.isUsable()) +    return 0; + +  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). +  // Used for directives with static scheduling. +  ExprResult NextLB, NextUB; +  if (isOpenMPWorksharingDirective(DKind)) { +    // LB + ST +    NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); +    if (!NextLB.isUsable()) +      return 0; +    // LB = LB + ST +    NextLB = +        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); +    NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); +    if (!NextLB.isUsable()) +      return 0; +    // UB + ST +    NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); +    if (!NextUB.isUsable()) +      return 0; +    // UB = UB + ST +    NextUB = +        SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); +    NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); +    if (!NextUB.isUsable()) +      return 0; +  } + +  // Build updates and final values of the loop counters. +  bool HasErrors = false; +  Built.Counters.resize(NestedLoopCount); +  Built.Updates.resize(NestedLoopCount); +  Built.Finals.resize(NestedLoopCount); +  { +    ExprResult Div; +    // Go from inner nested loop to outer. +    for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { +      LoopIterationSpace &IS = IterSpaces[Cnt]; +      SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); +      // Build: Iter = (IV / Div) % IS.NumIters +      // where Div is product of previous iterations' IS.NumIters. +      ExprResult Iter; +      if (Div.isUsable()) { +        Iter = +            SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); +      } else { +        Iter = IV; +        assert((Cnt == (int)NestedLoopCount - 1) && +               "unusable div expected on first iteration only"); +      } + +      if (Cnt != 0 && Iter.isUsable()) +        Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), +                                  IS.NumIterations); +      if (!Iter.isUsable()) { +        HasErrors = true; +        break; +      } + +      // Build update: IS.CounterVar = IS.Start + Iter * IS.Step +      ExprResult Update = +          BuildCounterUpdate(SemaRef, CurScope, UpdLoc, IS.CounterVar, +                             IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); +      if (!Update.isUsable()) { +        HasErrors = true; +        break; +      } + +      // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step +      ExprResult Final = BuildCounterUpdate( +          SemaRef, CurScope, UpdLoc, IS.CounterVar, IS.CounterInit, +          IS.NumIterations, IS.CounterStep, IS.Subtract); +      if (!Final.isUsable()) { +        HasErrors = true; +        break; +      } + +      // Build Div for the next iteration: Div <- Div * IS.NumIters +      if (Cnt != 0) { +        if (Div.isUnset()) +          Div = IS.NumIterations; +        else +          Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), +                                   IS.NumIterations); + +        // Add parentheses (for debugging purposes only). +        if (Div.isUsable()) +          Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); +        if (!Div.isUsable()) { +          HasErrors = true; +          break; +        } +      } +      if (!Update.isUsable() || !Final.isUsable()) { +        HasErrors = true; +        break; +      } +      // Save results +      Built.Counters[Cnt] = IS.CounterVar; +      Built.Updates[Cnt] = Update.get(); +      Built.Finals[Cnt] = Final.get(); +    } +  } + +  if (HasErrors) +    return 0; + +  // Save results +  Built.IterationVarRef = IV.get(); +  Built.LastIteration = LastIteration.get(); +  Built.CalcLastIteration = CalcLastIteration.get(); +  Built.PreCond = PreCond.get(); +  Built.Cond = Cond.get(); +  Built.SeparatedCond = SeparatedCond.get(); +  Built.Init = Init.get(); +  Built.Inc = Inc.get(); +  Built.LB = LB.get(); +  Built.UB = UB.get(); +  Built.IL = IL.get(); +  Built.ST = ST.get(); +  Built.EUB = EUB.get(); +  Built.NLB = NextLB.get(); +  Built.NUB = NextUB.get(); +    return NestedLoopCount;  } @@ -2060,32 +2947,60 @@ StmtResult Sema::ActOnOpenMPSimdDirective(      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,      SourceLocation EndLoc,      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { +  OMPLoopDirective::HelperExprs B;    // In presence of clause 'collapse', it will define the nested loops number.    unsigned NestedLoopCount =        CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this, -                      *DSAStack, VarsWithImplicitDSA); +                      *DSAStack, VarsWithImplicitDSA, B);    if (NestedLoopCount == 0)      return StmtError(); +  assert((CurContext->isDependentContext() || B.builtAll()) && +         "omp simd loop exprs were not built"); +    getCurFunction()->setHasBranchProtectedScope();    return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, -                                  Clauses, AStmt); +                                  Clauses, AStmt, B);  }  StmtResult Sema::ActOnOpenMPForDirective(      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,      SourceLocation EndLoc,      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { +  OMPLoopDirective::HelperExprs B;    // In presence of clause 'collapse', it will define the nested loops number.    unsigned NestedLoopCount =        CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this, -                      *DSAStack, VarsWithImplicitDSA); +                      *DSAStack, VarsWithImplicitDSA, B);    if (NestedLoopCount == 0)      return StmtError(); +  assert((CurContext->isDependentContext() || B.builtAll()) && +         "omp for loop exprs were not built"); +    getCurFunction()->setHasBranchProtectedScope();    return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, -                                 Clauses, AStmt); +                                 Clauses, AStmt, B); +} + +StmtResult Sema::ActOnOpenMPForSimdDirective( +    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, +    SourceLocation EndLoc, +    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { +  OMPLoopDirective::HelperExprs B; +  // In presence of clause 'collapse', it will define the nested loops number. +  unsigned NestedLoopCount = +      CheckOpenMPLoop(OMPD_for_simd, GetCollapseNumberExpr(Clauses), AStmt, +                      *this, *DSAStack, VarsWithImplicitDSA, B); +  if (NestedLoopCount == 0) +    return StmtError(); + +  assert((CurContext->isDependentContext() || B.builtAll()) && +         "omp for simd loop exprs were not built"); + +  getCurFunction()->setHasBranchProtectedScope(); +  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, +                                     Clauses, AStmt, B);  }  StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -2178,16 +3093,46 @@ StmtResult Sema::ActOnOpenMPParallelForDirective(    // longjmp() and throw() must not violate the entry/exit criteria.    CS->getCapturedDecl()->setNothrow(); +  OMPLoopDirective::HelperExprs B;    // In presence of clause 'collapse', it will define the nested loops number.    unsigned NestedLoopCount =        CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt, -                      *this, *DSAStack, VarsWithImplicitDSA); +                      *this, *DSAStack, VarsWithImplicitDSA, B);    if (NestedLoopCount == 0)      return StmtError(); +  assert((CurContext->isDependentContext() || B.builtAll()) && +         "omp parallel for loop exprs were not built"); +    getCurFunction()->setHasBranchProtectedScope();    return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, -                                         NestedLoopCount, Clauses, AStmt); +                                         NestedLoopCount, Clauses, AStmt, B); +} + +StmtResult Sema::ActOnOpenMPParallelForSimdDirective( +    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, +    SourceLocation EndLoc, +    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); +  CapturedStmt *CS = cast<CapturedStmt>(AStmt); +  // 1.2.2 OpenMP Language Terminology +  // Structured block - An executable statement with a single entry at the +  // top and a single exit at the bottom. +  // The point of exit cannot be a branch out of the structured block. +  // longjmp() and throw() must not violate the entry/exit criteria. +  CS->getCapturedDecl()->setNothrow(); + +  OMPLoopDirective::HelperExprs B; +  // In presence of clause 'collapse', it will define the nested loops number. +  unsigned NestedLoopCount = +      CheckOpenMPLoop(OMPD_parallel_for_simd, GetCollapseNumberExpr(Clauses), +                      AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); +  if (NestedLoopCount == 0) +    return StmtError(); + +  getCurFunction()->setHasBranchProtectedScope(); +  return OMPParallelForSimdDirective::Create( +      Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);  }  StmtResult @@ -2264,6 +3209,271 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,    return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);  } +StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, +                                             SourceLocation StartLoc, +                                             SourceLocation EndLoc) { +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + +  getCurFunction()->setHasBranchProtectedScope(); + +  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt); +} + +StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, +                                            Stmt *AStmt, +                                            SourceLocation StartLoc, +                                            SourceLocation EndLoc) { +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); +  auto CS = cast<CapturedStmt>(AStmt); +  // 1.2.2 OpenMP Language Terminology +  // Structured block - An executable statement with a single entry at the +  // top and a single exit at the bottom. +  // The point of exit cannot be a branch out of the structured block. +  // longjmp() and throw() must not violate the entry/exit criteria. +  // TODO further analysis of associated statements and clauses. +  OpenMPClauseKind AtomicKind = OMPC_unknown; +  SourceLocation AtomicKindLoc; +  for (auto *C : Clauses) { +    if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || +        C->getClauseKind() == OMPC_update || +        C->getClauseKind() == OMPC_capture) { +      if (AtomicKind != OMPC_unknown) { +        Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) +            << SourceRange(C->getLocStart(), C->getLocEnd()); +        Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) +            << getOpenMPClauseName(AtomicKind); +      } else { +        AtomicKind = C->getClauseKind(); +        AtomicKindLoc = C->getLocStart(); +      } +    } +  } + +  auto Body = CS->getCapturedStmt(); +  Expr *X = nullptr; +  Expr *V = nullptr; +  Expr *E = nullptr; +  // OpenMP [2.12.6, atomic Construct] +  // In the next expressions: +  // * x and v (as applicable) are both l-value expressions with scalar type. +  // * During the execution of an atomic region, multiple syntactic +  // occurrences of x must designate the same storage location. +  // * Neither of v and expr (as applicable) may access the storage location +  // designated by x. +  // * Neither of x and expr (as applicable) may access the storage location +  // designated by v. +  // * expr is an expression with scalar type. +  // * binop is one of +, *, -, /, &, ^, |, <<, or >>. +  // * binop, binop=, ++, and -- are not overloaded operators. +  // * The expression x binop expr must be numerically equivalent to x binop +  // (expr). This requirement is satisfied if the operators in expr have +  // precedence greater than binop, or by using parentheses around expr or +  // subexpressions of expr. +  // * The expression expr binop x must be numerically equivalent to (expr) +  // binop x. This requirement is satisfied if the operators in expr have +  // precedence equal to or greater than binop, or by using parentheses around +  // expr or subexpressions of expr. +  // * For forms that allow multiple occurrences of x, the number of times +  // that x is evaluated is unspecified. +  enum { +    NotAnExpression, +    NotAnAssignmentOp, +    NotAScalarType, +    NotAnLValue, +    NoError +  } ErrorFound = NoError; +  if (AtomicKind == OMPC_read) { +    SourceLocation ErrorLoc, NoteLoc; +    SourceRange ErrorRange, NoteRange; +    // If clause is read: +    //  v = x; +    if (auto AtomicBody = dyn_cast<Expr>(Body)) { +      auto AtomicBinOp = +          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); +      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { +        X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); +        V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); +        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && +            (V->isInstantiationDependent() || V->getType()->isScalarType())) { +          if (!X->isLValue() || !V->isLValue()) { +            auto NotLValueExpr = X->isLValue() ? V : X; +            ErrorFound = NotAnLValue; +            ErrorLoc = AtomicBinOp->getExprLoc(); +            ErrorRange = AtomicBinOp->getSourceRange(); +            NoteLoc = NotLValueExpr->getExprLoc(); +            NoteRange = NotLValueExpr->getSourceRange(); +          } +        } else if (!X->isInstantiationDependent() || +                   !V->isInstantiationDependent()) { +          auto NotScalarExpr = +              (X->isInstantiationDependent() || X->getType()->isScalarType()) +                  ? V +                  : X; +          ErrorFound = NotAScalarType; +          ErrorLoc = AtomicBinOp->getExprLoc(); +          ErrorRange = AtomicBinOp->getSourceRange(); +          NoteLoc = NotScalarExpr->getExprLoc(); +          NoteRange = NotScalarExpr->getSourceRange(); +        } +      } else { +        ErrorFound = NotAnAssignmentOp; +        ErrorLoc = AtomicBody->getExprLoc(); +        ErrorRange = AtomicBody->getSourceRange(); +        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() +                              : AtomicBody->getExprLoc(); +        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() +                                : AtomicBody->getSourceRange(); +      } +    } else { +      ErrorFound = NotAnExpression; +      NoteLoc = ErrorLoc = Body->getLocStart(); +      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); +    } +    if (ErrorFound != NoError) { +      Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) +          << ErrorRange; +      Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound +                                                      << NoteRange; +      return StmtError(); +    } else if (CurContext->isDependentContext()) +      V = X = nullptr; +  } else if (AtomicKind == OMPC_write) { +    SourceLocation ErrorLoc, NoteLoc; +    SourceRange ErrorRange, NoteRange; +    // If clause is write: +    //  x = expr; +    if (auto AtomicBody = dyn_cast<Expr>(Body)) { +      auto AtomicBinOp = +          dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); +      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { +        X = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); +        E = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); +        if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && +            (E->isInstantiationDependent() || E->getType()->isScalarType())) { +          if (!X->isLValue()) { +            ErrorFound = NotAnLValue; +            ErrorLoc = AtomicBinOp->getExprLoc(); +            ErrorRange = AtomicBinOp->getSourceRange(); +            NoteLoc = X->getExprLoc(); +            NoteRange = X->getSourceRange(); +          } +        } else if (!X->isInstantiationDependent() || +                   !E->isInstantiationDependent()) { +          auto NotScalarExpr = +              (X->isInstantiationDependent() || X->getType()->isScalarType()) +                  ? E +                  : X; +          ErrorFound = NotAScalarType; +          ErrorLoc = AtomicBinOp->getExprLoc(); +          ErrorRange = AtomicBinOp->getSourceRange(); +          NoteLoc = NotScalarExpr->getExprLoc(); +          NoteRange = NotScalarExpr->getSourceRange(); +        } +      } else { +        ErrorFound = NotAnAssignmentOp; +        ErrorLoc = AtomicBody->getExprLoc(); +        ErrorRange = AtomicBody->getSourceRange(); +        NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() +                              : AtomicBody->getExprLoc(); +        NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() +                                : AtomicBody->getSourceRange(); +      } +    } else { +      ErrorFound = NotAnExpression; +      NoteLoc = ErrorLoc = Body->getLocStart(); +      NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); +    } +    if (ErrorFound != NoError) { +      Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) +          << ErrorRange; +      Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound +                                                      << NoteRange; +      return StmtError(); +    } else if (CurContext->isDependentContext()) +      E = X = nullptr; +  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { +    if (!isa<Expr>(Body)) { +      Diag(Body->getLocStart(), +           diag::err_omp_atomic_update_not_expression_statement) +          << (AtomicKind == OMPC_update); +      return StmtError(); +    } +  } else if (AtomicKind == OMPC_capture) { +    if (isa<Expr>(Body) && !isa<BinaryOperator>(Body)) { +      Diag(Body->getLocStart(), +           diag::err_omp_atomic_capture_not_expression_statement); +      return StmtError(); +    } else if (!isa<Expr>(Body) && !isa<CompoundStmt>(Body)) { +      Diag(Body->getLocStart(), +           diag::err_omp_atomic_capture_not_compound_statement); +      return StmtError(); +    } +  } + +  getCurFunction()->setHasBranchProtectedScope(); + +  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, +                                    X, V, E); +} + +StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, +                                            Stmt *AStmt, +                                            SourceLocation StartLoc, +                                            SourceLocation EndLoc) { +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + +  // OpenMP [2.16, Nesting of Regions] +  // If specified, a teams construct must be contained within a target +  // construct. That target construct must contain no statements or directives +  // outside of the teams construct. +  if (DSAStack->hasInnerTeamsRegion()) { +    auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); +    bool OMPTeamsFound = true; +    if (auto *CS = dyn_cast<CompoundStmt>(S)) { +      auto I = CS->body_begin(); +      while (I != CS->body_end()) { +        auto OED = dyn_cast<OMPExecutableDirective>(*I); +        if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { +          OMPTeamsFound = false; +          break; +        } +        ++I; +      } +      assert(I != CS->body_end() && "Not found statement"); +      S = *I; +    } +    if (!OMPTeamsFound) { +      Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); +      Diag(DSAStack->getInnerTeamsRegionLoc(), +           diag::note_omp_nested_teams_construct_here); +      Diag(S->getLocStart(), diag::note_omp_nested_statement_here) +          << isa<OMPExecutableDirective>(S); +      return StmtError(); +    } +  } + +  getCurFunction()->setHasBranchProtectedScope(); + +  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); +} + +StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, +                                           Stmt *AStmt, SourceLocation StartLoc, +                                           SourceLocation EndLoc) { +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); +  CapturedStmt *CS = cast<CapturedStmt>(AStmt); +  // 1.2.2 OpenMP Language Terminology +  // Structured block - An executable statement with a single entry at the +  // top and a single exit at the bottom. +  // The point of exit cannot be a branch out of the structured block. +  // longjmp() and throw() must not violate the entry/exit criteria. +  CS->getCapturedDecl()->setNothrow(); + +  getCurFunction()->setHasBranchProtectedScope(); + +  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); +} +  OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,                                               SourceLocation StartLoc,                                               SourceLocation LParenLoc, @@ -2303,6 +3513,11 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,    case OMPC_mergeable:    case OMPC_threadprivate:    case OMPC_flush: +  case OMPC_read: +  case OMPC_write: +  case OMPC_update: +  case OMPC_capture: +  case OMPC_seq_cst:    case OMPC_unknown:      llvm_unreachable("Clause is not allowed.");    } @@ -2345,7 +3560,6 @@ OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,    return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);  } -  ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,                                                          Expr *Op) {    if (!Op) @@ -2396,7 +3610,6 @@ OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,                                               SourceLocation EndLoc) {    Expr *ValExpr = NumThreads;    if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() && -      !NumThreads->isInstantiationDependent() &&        !NumThreads->containsUnexpandedParameterPack()) {      SourceLocation NumThreadsLoc = NumThreads->getLocStart();      ExprResult Val = @@ -2437,6 +3650,11 @@ ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,          << getOpenMPClauseName(CKind) << E->getSourceRange();      return ExprError();    } +  if (CKind == OMPC_aligned && !Result.isPowerOf2()) { +    Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) +        << E->getSourceRange(); +    return ExprError(); +  }    return ICE;  } @@ -2506,6 +3724,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(    case OMPC_mergeable:    case OMPC_threadprivate:    case OMPC_flush: +  case OMPC_read: +  case OMPC_write: +  case OMPC_update: +  case OMPC_capture: +  case OMPC_seq_cst:    case OMPC_unknown:      llvm_unreachable("Clause is not allowed.");    } @@ -2621,6 +3844,11 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(    case OMPC_mergeable:    case OMPC_threadprivate:    case OMPC_flush: +  case OMPC_read: +  case OMPC_write: +  case OMPC_update: +  case OMPC_capture: +  case OMPC_seq_cst:    case OMPC_unknown:      llvm_unreachable("Clause is not allowed.");    } @@ -2700,6 +3928,21 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,    case OMPC_mergeable:      Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);      break; +  case OMPC_read: +    Res = ActOnOpenMPReadClause(StartLoc, EndLoc); +    break; +  case OMPC_write: +    Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); +    break; +  case OMPC_update: +    Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); +    break; +  case OMPC_capture: +    Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); +    break; +  case OMPC_seq_cst: +    Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); +    break;    case OMPC_if:    case OMPC_final:    case OMPC_num_threads: @@ -2727,6 +3970,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,  OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,                                            SourceLocation EndLoc) { +  DSAStack->setOrderedRegion();    return new (Context) OMPOrderedClause(StartLoc, EndLoc);  } @@ -2745,6 +3989,31 @@ OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,    return new (Context) OMPMergeableClause(StartLoc, EndLoc);  } +OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, +                                       SourceLocation EndLoc) { +  return new (Context) OMPReadClause(StartLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, +                                        SourceLocation EndLoc) { +  return new (Context) OMPWriteClause(StartLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, +                                         SourceLocation EndLoc) { +  return new (Context) OMPUpdateClause(StartLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, +                                          SourceLocation EndLoc) { +  return new (Context) OMPCaptureClause(StartLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, +                                         SourceLocation EndLoc) { +  return new (Context) OMPSeqCstClause(StartLoc, EndLoc); +} +  OMPClause *Sema::ActOnOpenMPVarListClause(      OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,      SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, @@ -2798,6 +4067,11 @@ OMPClause *Sema::ActOnOpenMPVarListClause(    case OMPC_untied:    case OMPC_mergeable:    case OMPC_threadprivate: +  case OMPC_read: +  case OMPC_write: +  case OMPC_update: +  case OMPC_capture: +  case OMPC_seq_cst:    case OMPC_unknown:      llvm_unreachable("Clause is not allowed.");    } @@ -2809,11 +4083,13 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,                                            SourceLocation LParenLoc,                                            SourceLocation EndLoc) {    SmallVector<Expr *, 8> Vars; +  SmallVector<Expr *, 8> PrivateCopies;    for (auto &RefExpr : VarList) {      assert(RefExpr && "NULL expr in OpenMP private clause.");      if (isa<DependentScopeDeclRefExpr>(RefExpr)) {        // It will be analyzed later.        Vars.push_back(RefExpr); +      PrivateCopies.push_back(nullptr);        continue;      } @@ -2835,6 +4111,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,      if (Type->isDependentType() || Type->isInstantiationDependentType()) {        // It will be analyzed later.        Vars.push_back(DE); +      PrivateCopies.push_back(nullptr);        continue;      } @@ -2860,54 +4137,8 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,      //  A variable of class type (or array thereof) that appears in a private      //  clause requires an accessible, unambiguous default constructor for the      //  class type. -    while (Type.getNonReferenceType()->isArrayType()) { -      Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr()) -                 ->getElementType(); -    } -    CXXRecordDecl *RD = getLangOpts().CPlusPlus -                            ? Type.getNonReferenceType()->getAsCXXRecordDecl() -                            : nullptr; -    // FIXME This code must be replaced by actual constructing/destructing of -    // the private variable. -    if (RD) { -      CXXConstructorDecl *CD = LookupDefaultConstructor(RD); -      PartialDiagnostic PD = -          PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); -      if (!CD || -          CheckConstructorAccess(ELoc, CD, -                                 InitializedEntity::InitializeTemporary(Type), -                                 CD->getAccess(), PD) == AR_inaccessible || -          CD->isDeleted()) { -        Diag(ELoc, diag::err_omp_required_method) -            << getOpenMPClauseName(OMPC_private) << 0; -        bool IsDecl = VD->isThisDeclarationADefinition(Context) == -                      VarDecl::DeclarationOnly; -        Diag(VD->getLocation(), -             IsDecl ? diag::note_previous_decl : diag::note_defined_here) -            << VD; -        Diag(RD->getLocation(), diag::note_previous_decl) << RD; -        continue; -      } -      MarkFunctionReferenced(ELoc, CD); -      DiagnoseUseOfDecl(CD, ELoc); - -      CXXDestructorDecl *DD = RD->getDestructor(); -      if (DD) { -        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || -            DD->isDeleted()) { -          Diag(ELoc, diag::err_omp_required_method) -              << getOpenMPClauseName(OMPC_private) << 4; -          bool IsDecl = VD->isThisDeclarationADefinition(Context) == -                        VarDecl::DeclarationOnly; -          Diag(VD->getLocation(), -               IsDecl ? diag::note_previous_decl : diag::note_defined_here) -              << VD; -          Diag(RD->getLocation(), diag::note_previous_decl) << RD; -          continue; -        } -        MarkFunctionReferenced(ELoc, DD); -        DiagnoseUseOfDecl(DD, ELoc); -      } +    while (Type->isArrayType()) { +      Type = cast<ArrayType>(Type.getTypePtr())->getElementType();      }      // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced @@ -2925,14 +4156,59 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,        continue;      } +    // Generate helper private variable and initialize it with the default +    // value. The address of the original variable is replaced by the address of +    // the new private variable in CodeGen. This new variable is not added to +    // IdResolver, so the code in the OpenMP region uses original variable for +    // proper diagnostics. +    auto VDPrivate = +        VarDecl::Create(Context, CurContext, DE->getLocStart(), +                        DE->getExprLoc(), VD->getIdentifier(), VD->getType(), +                        VD->getTypeSourceInfo(), /*S*/ SC_Auto); +    ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto*/ false); +    if (VDPrivate->isInvalidDecl()) +      continue; +    CurContext->addDecl(VDPrivate); +    auto VDPrivateRefExpr = +        DeclRefExpr::Create(Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), +                            /*TemplateKWLoc*/ SourceLocation(), VDPrivate, +                            /*RefersToEnclosingVariableOrCapture*/ false, +                            /*NameLoc*/ SourceLocation(), DE->getType(), +                            /*VK*/ VK_LValue); +      DSAStack->addDSA(VD, DE, OMPC_private);      Vars.push_back(DE); +    PrivateCopies.push_back(VDPrivateRefExpr);    }    if (Vars.empty())      return nullptr; -  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); +  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, +                                  PrivateCopies); +} + +namespace { +class DiagsUninitializedSeveretyRAII { +private: +  DiagnosticsEngine &Diags; +  SourceLocation SavedLoc; +  bool IsIgnored; + +public: +  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, +                                 bool IsIgnored) +      : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { +    if (!IsIgnored) { +      Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, +                        /*Map*/ diag::Severity::Ignored, Loc); +    } +  } +  ~DiagsUninitializedSeveretyRAII() { +    if (!IsIgnored) +      Diags.popMappings(SavedLoc); +  } +};  }  OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, @@ -2940,6 +4216,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,                                                 SourceLocation LParenLoc,                                                 SourceLocation EndLoc) {    SmallVector<Expr *, 8> Vars; +  SmallVector<Expr *, 8> PrivateCopies; +  SmallVector<Expr *, 8> Inits;    bool IsImplicitClause =        StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();    auto ImplicitClauseLoc = DSAStack->getConstructLoc(); @@ -2949,11 +4227,13 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,      if (isa<DependentScopeDeclRefExpr>(RefExpr)) {        // It will be analyzed later.        Vars.push_back(RefExpr); +      PrivateCopies.push_back(nullptr); +      Inits.push_back(nullptr);        continue;      } -    SourceLocation ELoc = IsImplicitClause ? ImplicitClauseLoc -                                           : RefExpr->getExprLoc(); +    SourceLocation ELoc = +        IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();      // OpenMP [2.1, C/C++]      //  A list item is a variable name.      // OpenMP  [2.9.3.3, Restrictions, p.1] @@ -2971,6 +4251,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,      if (Type->isDependentType() || Type->isInstantiationDependentType()) {        // It will be analyzed later.        Vars.push_back(DE); +      PrivateCopies.push_back(nullptr); +      Inits.push_back(nullptr);        continue;      } @@ -3004,65 +4286,6 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,      //  clause requires an accessible, unambiguous copy constructor for the      //  class type.      Type = Context.getBaseElementType(Type); -    CXXRecordDecl *RD = getLangOpts().CPlusPlus -                            ? Type.getNonReferenceType()->getAsCXXRecordDecl() -                            : nullptr; -    // FIXME This code must be replaced by actual constructing/destructing of -    // the firstprivate variable. -    if (RD) { -      CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0); -      PartialDiagnostic PD = -          PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); -      if (!CD || -          CheckConstructorAccess(ELoc, CD, -                                 InitializedEntity::InitializeTemporary(Type), -                                 CD->getAccess(), PD) == AR_inaccessible || -          CD->isDeleted()) { -        if (IsImplicitClause) { -          Diag(ImplicitClauseLoc, -               diag::err_omp_task_predetermined_firstprivate_required_method) -              << 0; -          Diag(RefExpr->getExprLoc(), diag::note_used_here); -        } else { -          Diag(ELoc, diag::err_omp_required_method) -              << getOpenMPClauseName(OMPC_firstprivate) << 1; -        } -        bool IsDecl = VD->isThisDeclarationADefinition(Context) == -                      VarDecl::DeclarationOnly; -        Diag(VD->getLocation(), -             IsDecl ? diag::note_previous_decl : diag::note_defined_here) -            << VD; -        Diag(RD->getLocation(), diag::note_previous_decl) << RD; -        continue; -      } -      MarkFunctionReferenced(ELoc, CD); -      DiagnoseUseOfDecl(CD, ELoc); - -      CXXDestructorDecl *DD = RD->getDestructor(); -      if (DD) { -        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || -            DD->isDeleted()) { -          if (IsImplicitClause) { -            Diag(ImplicitClauseLoc, -                 diag::err_omp_task_predetermined_firstprivate_required_method) -                << 1; -            Diag(RefExpr->getExprLoc(), diag::note_used_here); -          } else { -            Diag(ELoc, diag::err_omp_required_method) -                << getOpenMPClauseName(OMPC_firstprivate) << 4; -          } -          bool IsDecl = VD->isThisDeclarationADefinition(Context) == -                        VarDecl::DeclarationOnly; -          Diag(VD->getLocation(), -               IsDecl ? diag::note_previous_decl : diag::note_defined_here) -              << VD; -          Diag(RD->getLocation(), diag::note_previous_decl) << RD; -          continue; -        } -        MarkFunctionReferenced(ELoc, DD); -        DiagnoseUseOfDecl(DD, ELoc); -      } -    }      // If an implicit firstprivate variable found it was checked already.      if (!IsImplicitClause) { @@ -3152,15 +4375,75 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,        }      } +    Type = Type.getUnqualifiedType(); +    auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(), +                                     ELoc, VD->getIdentifier(), VD->getType(), +                                     VD->getTypeSourceInfo(), /*S*/ SC_Auto); +    // Generate helper private variable and initialize it with the value of the +    // original variable. The address of the original variable is replaced by +    // the address of the new private variable in the CodeGen. This new variable +    // is not added to IdResolver, so the code in the OpenMP region uses +    // original variable for proper diagnostics and variable capturing. +    Expr *VDInitRefExpr = nullptr; +    // For arrays generate initializer for single element and replace it by the +    // original array element in CodeGen. +    if (DE->getType()->isArrayType()) { +      auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(), +                                    ELoc, VD->getIdentifier(), Type, +                                    VD->getTypeSourceInfo(), /*S*/ SC_Auto); +      CurContext->addHiddenDecl(VDInit); +      VDInitRefExpr = DeclRefExpr::Create( +          Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), +          /*TemplateKWLoc*/ SourceLocation(), VDInit, +          /*RefersToEnclosingVariableOrCapture*/ true, ELoc, Type, +          /*VK*/ VK_LValue); +      VDInit->setIsUsed(); +      auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); +      InitializedEntity Entity = InitializedEntity::InitializeVariable(VDInit); +      InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); + +      InitializationSequence InitSeq(*this, Entity, Kind, Init); +      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); +      if (Result.isInvalid()) +        VDPrivate->setInvalidDecl(); +      else +        VDPrivate->setInit(Result.getAs<Expr>()); +    } else { +      AddInitializerToDecl( +          VDPrivate, +          DefaultLvalueConversion( +              DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), +                                  SourceLocation(), DE->getDecl(), +                                  /*RefersToEnclosingVariableOrCapture=*/true, +                                  DE->getExprLoc(), DE->getType(), +                                  /*VK=*/VK_LValue)).get(), +          /*DirectInit=*/false, /*TypeMayContainAuto=*/false); +    } +    if (VDPrivate->isInvalidDecl()) { +      if (IsImplicitClause) { +        Diag(DE->getExprLoc(), +             diag::note_omp_task_predetermined_firstprivate_here); +      } +      continue; +    } +    CurContext->addDecl(VDPrivate); +    auto VDPrivateRefExpr = +        DeclRefExpr::Create(Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), +                            /*TemplateKWLoc*/ SourceLocation(), VDPrivate, +                            /*RefersToEnclosingVariableOrCapture*/ false, +                            DE->getLocStart(), DE->getType(), +                            /*VK*/ VK_LValue);      DSAStack->addDSA(VD, DE, OMPC_firstprivate);      Vars.push_back(DE); +    PrivateCopies.push_back(VDPrivateRefExpr); +    Inits.push_back(VDInitRefExpr);    }    if (Vars.empty())      return nullptr;    return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, -                                       Vars); +                                       Vars, PrivateCopies, Inits);  }  OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, @@ -4099,4 +5382,3 @@ OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,    return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);  } -#undef DSAStack diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 03001d89f07e..9195ee59075d 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -35,7 +35,7 @@  #include <algorithm>  #include <cstdlib> -namespace clang { +using namespace clang;  using namespace sema;  /// A convenience routine for creating a decayed reference to a function. @@ -102,43 +102,9 @@ CompareDerivedToBaseConversions(Sema &S,                                  const StandardConversionSequence& SCS1,                                  const StandardConversionSequence& SCS2); - - -/// GetConversionCategory - Retrieve the implicit conversion -/// category corresponding to the given implicit conversion kind. -ImplicitConversionCategory -GetConversionCategory(ImplicitConversionKind Kind) { -  static const ImplicitConversionCategory -    Category[(int)ICK_Num_Conversion_Kinds] = { -    ICC_Identity, -    ICC_Lvalue_Transformation, -    ICC_Lvalue_Transformation, -    ICC_Lvalue_Transformation, -    ICC_Identity, -    ICC_Qualification_Adjustment, -    ICC_Promotion, -    ICC_Promotion, -    ICC_Promotion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion, -    ICC_Conversion -  }; -  return Category[(int)Kind]; -} -  /// GetConversionRank - Retrieve the implicit conversion rank  /// corresponding to the given implicit conversion kind. -ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) { +ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) {    static const ImplicitConversionRank      Rank[(int)ICK_Num_Conversion_Kinds] = {      ICR_Exact_Match, @@ -171,7 +137,7 @@ ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) {  /// GetImplicitConversionName - Return the name of this kind of  /// implicit conversion. -const char* GetImplicitConversionName(ImplicitConversionKind Kind) { +static const char* GetImplicitConversionName(ImplicitConversionKind Kind) {    static const char* const Name[(int)ICK_Num_Conversion_Kinds] = {      "No conversion",      "Lvalue-to-rvalue", @@ -195,7 +161,7 @@ const char* GetImplicitConversionName(ImplicitConversionKind Kind) {      "Vector splat",      "Complex-real conversion",      "Block Pointer conversion", -    "Transparent Union Conversion" +    "Transparent Union Conversion",      "Writeback conversion"    };    return Name[Kind]; @@ -568,9 +534,10 @@ namespace {  /// \brief Convert from Sema's representation of template deduction information  /// to the form used in overload-candidate information. -DeductionFailureInfo MakeDeductionFailureInfo(ASTContext &Context, -                                              Sema::TemplateDeductionResult TDK, -                                              TemplateDeductionInfo &Info) { +DeductionFailureInfo +clang::MakeDeductionFailureInfo(ASTContext &Context, +                                Sema::TemplateDeductionResult TDK, +                                TemplateDeductionInfo &Info) {    DeductionFailureInfo Result;    Result.Result = static_cast<unsigned>(TDK);    Result.HasDiagnostic = false; @@ -1067,7 +1034,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,      // is a redeclaration of OldMethod.      unsigned OldQuals = OldMethod->getTypeQualifiers();      unsigned NewQuals = NewMethod->getTypeQualifiers(); -    if (!getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() && +    if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() &&          !isa<CXXConstructorDecl>(NewMethod))        NewQuals |= Qualifiers::Const; @@ -1268,11 +1235,11 @@ Sema::TryImplicitConversion(Expr *From, QualType ToType,                              bool InOverloadResolution,                              bool CStyle,                              bool AllowObjCWritebackConversion) { -  return clang::TryImplicitConversion(*this, From, ToType,  -                                      SuppressUserConversions, AllowExplicit, -                                      InOverloadResolution, CStyle,  -                                      AllowObjCWritebackConversion, -                                      /*AllowObjCConversionOnExplicit=*/false); +  return ::TryImplicitConversion(*this, From, ToType,  +                                 SuppressUserConversions, AllowExplicit, +                                 InOverloadResolution, CStyle,  +                                 AllowObjCWritebackConversion, +                                 /*AllowObjCConversionOnExplicit=*/false);  }  /// PerformImplicitConversion - Perform an implicit conversion of the @@ -1301,13 +1268,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,    if (getLangOpts().ObjC1)      CheckObjCBridgeRelatedConversions(From->getLocStart(),                                        ToType, From->getType(), From); -  ICS = clang::TryImplicitConversion(*this, From, ToType, -                                     /*SuppressUserConversions=*/false, -                                     AllowExplicit, -                                     /*InOverloadResolution=*/false, -                                     /*CStyle=*/false, -                                     AllowObjCWritebackConversion, -                                     /*AllowObjCConversionOnExplicit=*/false); +  ICS = ::TryImplicitConversion(*this, From, ToType, +                                /*SuppressUserConversions=*/false, +                                AllowExplicit, +                                /*InOverloadResolution=*/false, +                                /*CStyle=*/false, +                                AllowObjCWritebackConversion, +                                /*AllowObjCConversionOnExplicit=*/false);    return PerformImplicitConversion(From, ToType, ICS, Action);  } @@ -1451,6 +1418,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,        // We were able to resolve the address of the overloaded function,        // so we can convert to the type of that function.        FromType = Fn->getType(); +      SCS.setFromType(FromType);        // we can sometimes resolve &foo<int> regardless of ToType, so check        // if the type matches (identity) or we are converting to bool @@ -3656,7 +3624,7 @@ CompareStandardConversionSequences(Sema &S,  /// CompareQualificationConversions - Compares two standard conversion  /// sequences to determine whether they can be ranked based on their  /// qualification conversions (C++ 13.3.3.2p3 bullet 3). -ImplicitConversionSequence::CompareKind +static ImplicitConversionSequence::CompareKind  CompareQualificationConversions(Sema &S,                                  const StandardConversionSequence& SCS1,                                  const StandardConversionSequence& SCS2) { @@ -3769,7 +3737,7 @@ CompareQualificationConversions(Sema &S,  /// various kinds of derived-to-base conversions (C++  /// [over.ics.rank]p4b3).  As part of these checks, we also look at  /// conversions between Objective-C interface types. -ImplicitConversionSequence::CompareKind +static ImplicitConversionSequence::CompareKind  CompareDerivedToBaseConversions(Sema &S,                                  const StandardConversionSequence& SCS1,                                  const StandardConversionSequence& SCS2) { @@ -4849,9 +4817,8 @@ Sema::PerformObjectArgumentInitialization(Expr *From,    // Note that we always use the true parent context when performing    // the actual argument initialization. -  ImplicitConversionSequence ICS -    = TryObjectArgumentInitialization(*this, From->getType(), FromClassification, -                                      Method, Method->getParent()); +  ImplicitConversionSequence ICS = TryObjectArgumentInitialization( +      *this, From->getType(), FromClassification, Method, Method->getParent());    if (ICS.isBad()) {      if (ICS.Bad.Kind == BadConversionSequence::bad_qualifiers) {        Qualifiers FromQs = FromRecordType.getQualifiers(); @@ -4927,41 +4894,51 @@ static bool CheckConvertedConstantConversions(Sema &S,    // conversions are fine.    switch (SCS.Second) {    case ICK_Identity: +  case ICK_NoReturn_Adjustment:    case ICK_Integral_Promotion: -  case ICK_Integral_Conversion: -  case ICK_Zero_Event_Conversion: +  case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.      return true;    case ICK_Boolean_Conversion:      // Conversion from an integral or unscoped enumeration type to bool is -    // classified as ICK_Boolean_Conversion, but it's also an integral -    // conversion, so it's permitted in a converted constant expression. +    // classified as ICK_Boolean_Conversion, but it's also arguably an integral +    // conversion, so we allow it in a converted constant expression. +    // +    // FIXME: Per core issue 1407, we should not allow this, but that breaks +    // a lot of popular code. We should at least add a warning for this +    // (non-conforming) extension.      return SCS.getFromType()->isIntegralOrUnscopedEnumerationType() &&             SCS.getToType(2)->isBooleanType(); +  case ICK_Pointer_Conversion: +  case ICK_Pointer_Member: +    // C++1z: null pointer conversions and null member pointer conversions are +    // only permitted if the source type is std::nullptr_t. +    return SCS.getFromType()->isNullPtrType(); + +  case ICK_Floating_Promotion: +  case ICK_Complex_Promotion: +  case ICK_Floating_Conversion: +  case ICK_Complex_Conversion:    case ICK_Floating_Integral: +  case ICK_Compatible_Conversion: +  case ICK_Derived_To_Base: +  case ICK_Vector_Conversion: +  case ICK_Vector_Splat:    case ICK_Complex_Real: +  case ICK_Block_Pointer_Conversion: +  case ICK_TransparentUnionConversion: +  case ICK_Writeback_Conversion: +  case ICK_Zero_Event_Conversion:      return false;    case ICK_Lvalue_To_Rvalue:    case ICK_Array_To_Pointer:    case ICK_Function_To_Pointer: -  case ICK_NoReturn_Adjustment: +    llvm_unreachable("found a first conversion kind in Second"); +    case ICK_Qualification: -  case ICK_Compatible_Conversion: -  case ICK_Vector_Conversion: -  case ICK_Vector_Splat: -  case ICK_Derived_To_Base: -  case ICK_Pointer_Conversion: -  case ICK_Pointer_Member: -  case ICK_Block_Pointer_Conversion: -  case ICK_Writeback_Conversion: -  case ICK_Floating_Promotion: -  case ICK_Complex_Promotion: -  case ICK_Complex_Conversion: -  case ICK_Floating_Conversion: -  case ICK_TransparentUnionConversion: -    llvm_unreachable("unexpected second conversion kind"); +    llvm_unreachable("found a third conversion kind in Second");    case ICK_Num_Conversion_Kinds:      break; @@ -4973,67 +4950,71 @@ static bool CheckConvertedConstantConversions(Sema &S,  /// CheckConvertedConstantExpression - Check that the expression From is a  /// converted constant expression of type T, perform the conversion and produce  /// the converted expression, per C++11 [expr.const]p3. -ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, -                                                  llvm::APSInt &Value, -                                                  CCEKind CCE) { -  assert(LangOpts.CPlusPlus11 && "converted constant expression outside C++11"); -  assert(T->isIntegralOrEnumerationType() && "unexpected converted const type"); - -  if (checkPlaceholderForOverload(*this, From)) +static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, +                                                   QualType T, APValue &Value, +                                                   Sema::CCEKind CCE, +                                                   bool RequireInt) { +  assert(S.getLangOpts().CPlusPlus11 && +         "converted constant expression outside C++11"); + +  if (checkPlaceholderForOverload(S, From))      return ExprError(); -  // C++11 [expr.const]p3 with proposed wording fixes: -  //  A converted constant expression of type T is a core constant expression, -  //  implicitly converted to a prvalue of type T, where the converted -  //  expression is a literal constant expression and the implicit conversion -  //  sequence contains only user-defined conversions, lvalue-to-rvalue -  //  conversions, integral promotions, and integral conversions other than -  //  narrowing conversions. +  // C++1z [expr.const]p3: +  //  A converted constant expression of type T is an expression, +  //  implicitly converted to type T, where the converted +  //  expression is a constant expression and the implicit conversion +  //  sequence contains only [... list of conversions ...].    ImplicitConversionSequence ICS = -    TryImplicitConversion(From, T, +    TryCopyInitialization(S, From, T,                            /*SuppressUserConversions=*/false, -                          /*AllowExplicit=*/false,                            /*InOverloadResolution=*/false, -                          /*CStyle=*/false, -                          /*AllowObjcWritebackConversion=*/false); +                          /*AllowObjcWritebackConversion=*/false, +                          /*AllowExplicit=*/false);    StandardConversionSequence *SCS = nullptr;    switch (ICS.getKind()) {    case ImplicitConversionSequence::StandardConversion: -    if (!CheckConvertedConstantConversions(*this, ICS.Standard)) -      return Diag(From->getLocStart(), -                  diag::err_typecheck_converted_constant_expression_disallowed) -               << From->getType() << From->getSourceRange() << T;      SCS = &ICS.Standard;      break;    case ImplicitConversionSequence::UserDefinedConversion: -    // We are converting from class type to an integral or enumeration type, so -    // the Before sequence must be trivial. -    if (!CheckConvertedConstantConversions(*this, ICS.UserDefined.After)) -      return Diag(From->getLocStart(), -                  diag::err_typecheck_converted_constant_expression_disallowed) -               << From->getType() << From->getSourceRange() << T; +    // We are converting to a non-class type, so the Before sequence +    // must be trivial.      SCS = &ICS.UserDefined.After;      break;    case ImplicitConversionSequence::AmbiguousConversion:    case ImplicitConversionSequence::BadConversion: -    if (!DiagnoseMultipleUserDefinedConversion(From, T)) -      return Diag(From->getLocStart(), -                  diag::err_typecheck_converted_constant_expression) -                    << From->getType() << From->getSourceRange() << T; +    if (!S.DiagnoseMultipleUserDefinedConversion(From, T)) +      return S.Diag(From->getLocStart(), +                    diag::err_typecheck_converted_constant_expression) +                << From->getType() << From->getSourceRange() << T;      return ExprError();    case ImplicitConversionSequence::EllipsisConversion:      llvm_unreachable("ellipsis conversion in converted constant expression");    } -  ExprResult Result = PerformImplicitConversion(From, T, ICS, AA_Converting); +  // Check that we would only use permitted conversions. +  if (!CheckConvertedConstantConversions(S, *SCS)) { +    return S.Diag(From->getLocStart(), +                  diag::err_typecheck_converted_constant_expression_disallowed) +             << From->getType() << From->getSourceRange() << T; +  } +  // [...] and where the reference binding (if any) binds directly. +  if (SCS->ReferenceBinding && !SCS->DirectBinding) { +    return S.Diag(From->getLocStart(), +                  diag::err_typecheck_converted_constant_expression_indirect) +             << From->getType() << From->getSourceRange() << T; +  } + +  ExprResult Result = +      S.PerformImplicitConversion(From, T, ICS, Sema::AA_Converting);    if (Result.isInvalid())      return Result;    // Check for a narrowing implicit conversion.    APValue PreNarrowingValue;    QualType PreNarrowingType; -  switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue, +  switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue,                                  PreNarrowingType)) {    case NK_Variable_Narrowing:      // Implicit conversion to a narrower type, and the value is not a constant @@ -5042,13 +5023,13 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,      break;    case NK_Constant_Narrowing: -    Diag(From->getLocStart(), diag::ext_cce_narrowing) +    S.Diag(From->getLocStart(), diag::ext_cce_narrowing)        << CCE << /*Constant*/1 -      << PreNarrowingValue.getAsString(Context, PreNarrowingType) << T; +      << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T;      break;    case NK_Type_Narrowing: -    Diag(From->getLocStart(), diag::ext_cce_narrowing) +    S.Diag(From->getLocStart(), diag::ext_cce_narrowing)        << CCE << /*Constant*/0 << From->getType() << T;      break;    } @@ -5058,12 +5039,15 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,    Expr::EvalResult Eval;    Eval.Diag = &Notes; -  if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) { +  if ((T->isReferenceType() +           ? !Result.get()->EvaluateAsLValue(Eval, S.Context) +           : !Result.get()->EvaluateAsRValue(Eval, S.Context)) || +      (RequireInt && !Eval.Val.isInt())) {      // The expression can't be folded, so we can't keep it at this position in      // the AST.      Result = ExprError();    } else { -    Value = Eval.Val.getInt(); +    Value = Eval.Val;      if (Notes.empty()) {        // It's a constant expression. @@ -5074,16 +5058,34 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,    // It's not a constant expression. Produce an appropriate diagnostic.    if (Notes.size() == 1 &&        Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr) -    Diag(Notes[0].first, diag::err_expr_not_cce) << CCE; +    S.Diag(Notes[0].first, diag::err_expr_not_cce) << CCE;    else { -    Diag(From->getLocStart(), diag::err_expr_not_cce) +    S.Diag(From->getLocStart(), diag::err_expr_not_cce)        << CCE << From->getSourceRange();      for (unsigned I = 0; I < Notes.size(); ++I) -      Diag(Notes[I].first, Notes[I].second); +      S.Diag(Notes[I].first, Notes[I].second);    } -  return Result; +  return ExprError(); +} + +ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, +                                                  APValue &Value, CCEKind CCE) { +  return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false);  } +ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, +                                                  llvm::APSInt &Value, +                                                  CCEKind CCE) { +  assert(T->isIntegralOrEnumerationType() && "unexpected converted const type"); + +  APValue V; +  auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true); +  if (!R.isInvalid()) +    Value = V.getInt(); +  return R; +} + +  /// dropPointerConversions - If the given standard conversion sequence  /// involves any pointer conversions, remove them.  This may change  /// the result type of the conversion sequence. @@ -5364,14 +5366,14 @@ ExprResult Sema::PerformContextualImplicitConversion(      CXXConversionDecl *Conversion;      FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);      if (ConvTemplate) { -      if (getLangOpts().CPlusPlus1y) +      if (getLangOpts().CPlusPlus14)          Conversion = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());        else          continue; // C++11 does not consider conversion operator templates(?).      } else        Conversion = cast<CXXConversionDecl>(D); -    assert((!ConvTemplate || getLangOpts().CPlusPlus1y) && +    assert((!ConvTemplate || getLangOpts().CPlusPlus14) &&             "Conversion operator templates are considered potentially "             "viable in C++1y"); @@ -5384,7 +5386,7 @@ ExprResult Sema::PerformContextualImplicitConversion(          if (!ConvTemplate)            ExplicitConversions.addDecl(I.getDecl(), I.getAccess());        } else { -        if (!ConvTemplate && getLangOpts().CPlusPlus1y) { +        if (!ConvTemplate && getLangOpts().CPlusPlus14) {            if (ToType.isNull())              ToType = CurToType.getUnqualifiedType();            else if (HasUniqueTargetType && @@ -5396,7 +5398,7 @@ ExprResult Sema::PerformContextualImplicitConversion(      }    } -  if (getLangOpts().CPlusPlus1y) { +  if (getLangOpts().CPlusPlus14) {      // C++1y [conv]p6:      // ... An expression e of class type E appearing in such a context      // is said to be contextually implicitly converted to a specified @@ -5584,6 +5586,15 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,    // Overload resolution is always an unevaluated context.    EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); +  // Add this candidate +  OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); +  Candidate.FoundDecl = FoundDecl; +  Candidate.Function = Function; +  Candidate.Viable = true; +  Candidate.IsSurrogate = false; +  Candidate.IgnoreObjectArgument = false; +  Candidate.ExplicitCallArguments = Args.size(); +    if (Constructor) {      // C++ [class.copy]p3:      //   A member function template is never instantiated to perform the copy @@ -5592,19 +5603,13 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,      if (Args.size() == 1 &&          Constructor->isSpecializationCopyingObject() &&          (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) || -         IsDerivedFrom(Args[0]->getType(), ClassType))) +         IsDerivedFrom(Args[0]->getType(), ClassType))) { +      Candidate.Viable = false; +      Candidate.FailureKind = ovl_fail_illegal_constructor;        return; +    }    } -  // Add this candidate -  OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); -  Candidate.FoundDecl = FoundDecl; -  Candidate.Function = Function; -  Candidate.Viable = true; -  Candidate.IsSurrogate = false; -  Candidate.IgnoreObjectArgument = false; -  Candidate.ExplicitCallArguments = Args.size(); -    unsigned NumParams = Proto->getNumParams();    // (C++ 13.3.2p2): A candidate function having fewer than m @@ -5633,7 +5638,11 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,    // (CUDA B.1): Check for invalid calls between targets.    if (getLangOpts().CUDA)      if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) -      if (CheckCUDATarget(Caller, Function)) { +      // Skip the check for callers that are implicit members, because in this +      // case we may not yet know what the member's target is; the target is +      // inferred for the member automatically, based on the bases and fields of +      // the class. +      if (!Caller->isImplicit() && CheckCUDATarget(Caller, Function)) {          Candidate.Viable = false;          Candidate.FailureKind = ovl_fail_bad_target;          return; @@ -5676,6 +5685,93 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,    }  } +ObjCMethodDecl *Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, +                                       bool IsInstance) { +  SmallVector<ObjCMethodDecl*, 4> Methods; +  if (!CollectMultipleMethodsInGlobalPool(Sel, Methods, IsInstance)) +    return nullptr; +     +  for (unsigned b = 0, e = Methods.size(); b < e; b++) { +    bool Match = true; +    ObjCMethodDecl *Method = Methods[b]; +    unsigned NumNamedArgs = Sel.getNumArgs(); +    // Method might have more arguments than selector indicates. This is due +    // to addition of c-style arguments in method. +    if (Method->param_size() > NumNamedArgs) +      NumNamedArgs = Method->param_size(); +    if (Args.size() < NumNamedArgs) +      continue; +             +    for (unsigned i = 0; i < NumNamedArgs; i++) { +      // We can't do any type-checking on a type-dependent argument. +      if (Args[i]->isTypeDependent()) { +        Match = false; +        break; +      } +         +      ParmVarDecl *param = Method->parameters()[i]; +      Expr *argExpr = Args[i]; +      assert(argExpr && "SelectBestMethod(): missing expression"); +                 +      // Strip the unbridged-cast placeholder expression off unless it's +      // a consumed argument. +      if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) && +          !param->hasAttr<CFConsumedAttr>()) +        argExpr = stripARCUnbridgedCast(argExpr); +                 +      // If the parameter is __unknown_anytype, move on to the next method. +      if (param->getType() == Context.UnknownAnyTy) { +        Match = false; +        break; +      } +                 +      ImplicitConversionSequence ConversionState +        = TryCopyInitialization(*this, argExpr, param->getType(), +                                /*SuppressUserConversions*/false, +                                /*InOverloadResolution=*/true, +                                /*AllowObjCWritebackConversion=*/ +                                getLangOpts().ObjCAutoRefCount, +                                /*AllowExplicit*/false); +        if (ConversionState.isBad()) { +          Match = false; +          break; +        } +    } +    // Promote additional arguments to variadic methods. +    if (Match && Method->isVariadic()) { +      for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) { +        if (Args[i]->isTypeDependent()) { +          Match = false; +          break; +        } +        ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, +                                                          nullptr); +        if (Arg.isInvalid()) { +          Match = false; +          break; +        } +      } +    } else { +      // Check for extra arguments to non-variadic methods. +      if (Args.size() != NumNamedArgs) +        Match = false; +      else if (Match && NumNamedArgs == 0 && Methods.size() > 1) { +        // Special case when selectors have no argument. In this case, select +        // one with the most general result type of 'id'. +        for (unsigned b = 0, e = Methods.size(); b < e; b++) { +          QualType ReturnT = Methods[b]->getReturnType(); +          if (ReturnT->isObjCIdType()) +            return Methods[b]; +        } +      } +    } + +    if (Match) +      return Method; +  } +  return nullptr; +} +  static bool IsNotEnableIfAttr(Attr *A) { return !isa<EnableIfAttr>(A); }  EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, @@ -5696,6 +5792,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,    // Convert the arguments.    SmallVector<Expr *, 16> ConvertedArgs;    bool InitializationFailed = false; +  bool ContainsValueDependentExpr = false;    for (unsigned i = 0, e = Args.size(); i != e; ++i) {      if (i == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) &&          !cast<CXXMethodDecl>(Function)->isStatic() && @@ -5708,6 +5805,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,          InitializationFailed = true;          break;        } +      ContainsValueDependentExpr |= R.get()->isValueDependent();        ConvertedArgs.push_back(R.get());      } else {        ExprResult R = @@ -5720,6 +5818,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,          InitializationFailed = true;          break;        } +      ContainsValueDependentExpr |= R.get()->isValueDependent();        ConvertedArgs.push_back(R.get());      }    } @@ -5730,11 +5829,16 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,    for (AttrVec::iterator I = Attrs.begin(); I != E; ++I) {      APValue Result;      EnableIfAttr *EIA = cast<EnableIfAttr>(*I); +    if (EIA->getCond()->isValueDependent()) { +      // Don't even try now, we'll examine it after instantiation. +      continue; +    } +      if (!EIA->getCond()->EvaluateWithSubstitution( -            Result, Context, Function, -            ArrayRef<const Expr*>(ConvertedArgs.data(), -                                  ConvertedArgs.size())) || -        !Result.isInt() || !Result.getInt().getBoolValue()) { +            Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) { +      if (!ContainsValueDependentExpr) +        return EIA; +    } else if (!Result.isInt() || !Result.getInt().getBoolValue()) {        return EIA;      }    } @@ -5891,6 +5995,15 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,      }    } +  // (CUDA B.1): Check for invalid calls between targets. +  if (getLangOpts().CUDA) +    if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) +      if (CheckCUDATarget(Caller, Method)) { +        Candidate.Viable = false; +        Candidate.FailureKind = ovl_fail_bad_target; +        return; +      } +    // Determine the implicit conversion sequences for each of the    // arguments.    for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { @@ -6087,7 +6200,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,    // If the conversion function has an undeduced return type, trigger its    // deduction now. -  if (getLangOpts().CPlusPlus1y && ConvType->isUndeducedType()) { +  if (getLangOpts().CPlusPlus14 && ConvType->isUndeducedType()) {      if (DeduceReturnType(Conversion, From->getExprLoc()))        return;      ConvType = Conversion->getConversionType().getNonReferenceType(); @@ -6226,7 +6339,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,             "Can only end up with a standard conversion sequence or failure");    } -  if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, ArrayRef<Expr*>())) { +  if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) {      Candidate.Viable = false;      Candidate.FailureKind = ovl_fail_enable_if;      Candidate.DeductionFailure.Data = FailedAttr; @@ -6379,7 +6492,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,      }    } -  if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, ArrayRef<Expr*>())) { +  if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) {      Candidate.Viable = false;      Candidate.FailureKind = ovl_fail_enable_if;      Candidate.DeductionFailure.Data = FailedAttr; @@ -6610,7 +6723,7 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,                                               const Qualifiers &VisibleQuals) {    // Insert this type. -  if (!PointerTypes.insert(Ty)) +  if (!PointerTypes.insert(Ty).second)      return false;    QualType PointeeTy; @@ -6678,7 +6791,7 @@ bool  BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(      QualType Ty) {    // Insert this type. -  if (!MemberPointerTypes.insert(Ty)) +  if (!MemberPointerTypes.insert(Ty).second)      return false;    const MemberPointerType *PointerTy = Ty->getAs<MemberPointerType>(); @@ -7248,7 +7361,7 @@ public:             MemPtr != MemPtrEnd;             ++MemPtr) {          // Don't add the same builtin candidate twice. -        if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second)            continue;          QualType ParamTypes[2] = { *MemPtr, *MemPtr }; @@ -7323,7 +7436,7 @@ public:               PtrEnd = CandidateTypes[ArgIdx].pointer_end();             Ptr != PtrEnd; ++Ptr) {          // Don't add the same builtin candidate twice. -        if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second)            continue;          QualType ParamTypes[2] = { *Ptr, *Ptr }; @@ -7337,7 +7450,7 @@ public:          // Don't add the same builtin candidate twice, or if a user defined          // candidate exists. -        if (!AddedTypes.insert(CanonType) || +        if (!AddedTypes.insert(CanonType).second ||              UserDefinedBinaryOperators.count(std::make_pair(CanonType,                                                              CanonType)))            continue; @@ -7348,7 +7461,7 @@ public:        if (CandidateTypes[ArgIdx].hasNullPtrType()) {          CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); -        if (AddedTypes.insert(NullPtrTy) && +        if (AddedTypes.insert(NullPtrTy).second &&              !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy,                                                               NullPtrTy))) {            QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; @@ -7401,7 +7514,7 @@ public:          }          if (Op == OO_Minus) {            // ptrdiff_t operator-(T, T); -          if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr))) +          if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second)              continue;            QualType ParamTypes[2] = { *Ptr, *Ptr }; @@ -7530,7 +7643,7 @@ public:                  Enum = CandidateTypes[ArgIdx].enumeration_begin(),               EnumEnd = CandidateTypes[ArgIdx].enumeration_end();             Enum != EnumEnd; ++Enum) { -        if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second)            continue;          AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, CandidateSet); @@ -7540,7 +7653,7 @@ public:                  MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(),               MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end();             MemPtr != MemPtrEnd; ++MemPtr) { -        if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second)            continue;          AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, CandidateSet); @@ -7623,7 +7736,7 @@ public:               PtrEnd = CandidateTypes[1].pointer_end();             Ptr != PtrEnd; ++Ptr) {          // Make sure we don't add the same candidate twice. -        if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second)            continue;          QualType ParamTypes[2] = { @@ -7904,7 +8017,7 @@ public:                  Ptr = CandidateTypes[ArgIdx].pointer_begin(),               PtrEnd = CandidateTypes[ArgIdx].pointer_end();             Ptr != PtrEnd; ++Ptr) { -        if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second)            continue;          QualType ParamTypes[2] = { *Ptr, *Ptr }; @@ -7915,7 +8028,7 @@ public:                  MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(),               MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end();             MemPtr != MemPtrEnd; ++MemPtr) { -        if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr))) +        if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second)            continue;          QualType ParamTypes[2] = { *MemPtr, *MemPtr }; @@ -7930,7 +8043,7 @@ public:            if (!(*Enum)->getAs<EnumType>()->getDecl()->isScoped())              continue; -          if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum))) +          if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second)              continue;            QualType ParamTypes[2] = { *Enum, *Enum }; @@ -8184,12 +8297,10 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,  /// isBetterOverloadCandidate - Determines whether the first overload  /// candidate is a better candidate than the second (C++ 13.3.3p1). -bool -isBetterOverloadCandidate(Sema &S, -                          const OverloadCandidate &Cand1, -                          const OverloadCandidate &Cand2, -                          SourceLocation Loc, -                          bool UserDefinedConversion) { +bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, +                                      const OverloadCandidate &Cand2, +                                      SourceLocation Loc, +                                      bool UserDefinedConversion) {    // Define viable functions to be better candidates than non-viable    // functions.    if (!Cand2.Viable) @@ -8521,9 +8632,8 @@ void ImplicitConversionSequence::DiagnoseAmbiguousConversion(      S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I);  } -namespace { - -void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) { +static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, +                                  unsigned I) {    const ImplicitConversionSequence &Conv = Cand->Conversions[I];    assert(Conv.isBad());    assert(Cand->Function && "for now, candidate must be a function"); @@ -8741,8 +8851,8 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {  /// Additional arity mismatch diagnosis specific to a function overload  /// candidates. This is not covered by the more general DiagnoseArityMismatch()  /// over a candidate in any candidate set. -bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, -                        unsigned NumArgs) { +static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, +                               unsigned NumArgs) {    FunctionDecl *Fn = Cand->Function;    unsigned MinParams = Fn->getMinRequiredArguments(); @@ -8769,7 +8879,7 @@ bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand,  }  /// General arity mismatch diagnosis over a candidate in a candidate set. -void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { +static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) {    assert(isa<FunctionDecl>(D) &&        "The templated declaration should at least be a function"        " when diagnosing bad template argument deduction due to too many" @@ -8813,13 +8923,13 @@ void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) {  }  /// Arity mismatch diagnosis specific to a function overload candidate. -void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, -                           unsigned NumFormalArgs) { +static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, +                                  unsigned NumFormalArgs) {    if (!CheckArityMismatch(S, Cand, NumFormalArgs))      DiagnoseArityMismatch(S, Cand->Function, NumFormalArgs);  } -TemplateDecl *getDescribedTemplate(Decl *Templated) { +static TemplateDecl *getDescribedTemplate(Decl *Templated) {    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Templated))      return FD->getDescribedFunctionTemplate();    else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Templated)) @@ -8830,9 +8940,9 @@ TemplateDecl *getDescribedTemplate(Decl *Templated) {  }  /// Diagnose a failed template-argument deduction. -void DiagnoseBadDeduction(Sema &S, Decl *Templated, -                          DeductionFailureInfo &DeductionFailure, -                          unsigned NumArgs) { +static void DiagnoseBadDeduction(Sema &S, Decl *Templated, +                                 DeductionFailureInfo &DeductionFailure, +                                 unsigned NumArgs) {    TemplateParameter Param = DeductionFailure.getTemplateParameter();    NamedDecl *ParamD;    (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) || @@ -9019,7 +9129,8 @@ void DiagnoseBadDeduction(Sema &S, Decl *Templated,  }  /// Diagnose a failed template-argument deduction, for function calls. -void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs) { +static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, +                                 unsigned NumArgs) {    unsigned TDK = Cand->DeductionFailure.Result;    if (TDK == Sema::TDK_TooFewArguments || TDK == Sema::TDK_TooManyArguments) {      if (CheckArityMismatch(S, Cand, NumArgs)) @@ -9030,7 +9141,7 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs) {  }  /// CUDA: diagnose an invalid call across targets. -void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { +static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {    FunctionDecl *Caller = cast<FunctionDecl>(S.CurContext);    FunctionDecl *Callee = Cand->Function; @@ -9041,10 +9152,50 @@ void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {    OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Callee, FnDesc);    S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) -      << (unsigned) FnKind << CalleeTarget << CallerTarget; +      << (unsigned)FnKind << CalleeTarget << CallerTarget; + +  // This could be an implicit constructor for which we could not infer the +  // target due to a collsion. Diagnose that case. +  CXXMethodDecl *Meth = dyn_cast<CXXMethodDecl>(Callee); +  if (Meth != nullptr && Meth->isImplicit()) { +    CXXRecordDecl *ParentClass = Meth->getParent(); +    Sema::CXXSpecialMember CSM; + +    switch (FnKind) { +    default: +      return; +    case oc_implicit_default_constructor: +      CSM = Sema::CXXDefaultConstructor; +      break; +    case oc_implicit_copy_constructor: +      CSM = Sema::CXXCopyConstructor; +      break; +    case oc_implicit_move_constructor: +      CSM = Sema::CXXMoveConstructor; +      break; +    case oc_implicit_copy_assignment: +      CSM = Sema::CXXCopyAssignment; +      break; +    case oc_implicit_move_assignment: +      CSM = Sema::CXXMoveAssignment; +      break; +    }; + +    bool ConstRHS = false; +    if (Meth->getNumParams()) { +      if (const ReferenceType *RT = +              Meth->getParamDecl(0)->getType()->getAs<ReferenceType>()) { +        ConstRHS = RT->getPointeeType().isConstQualified(); +      } +    } + +    S.inferCUDATargetForImplicitSpecialMember(ParentClass, CSM, Meth, +                                              /* ConstRHS */ ConstRHS, +                                              /* Diagnose */ true); +  }  } -void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { +static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) {    FunctionDecl *Callee = Cand->Function;    EnableIfAttr *Attr = static_cast<EnableIfAttr*>(Cand->DeductionFailure.Data); @@ -9066,8 +9217,8 @@ void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) {  /// It would be great to be able to express per-candidate problems  /// more richly for those diagnostic clients that cared, but we'd  /// still have to be just as careful with the default diagnostics. -void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, -                           unsigned NumArgs) { +static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, +                                  unsigned NumArgs) {    FunctionDecl *Fn = Cand->Function;    // Note deleted candidates, but only if they're viable. @@ -9097,6 +9248,13 @@ void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,    case ovl_fail_bad_deduction:      return DiagnoseBadDeduction(S, Cand, NumArgs); +  case ovl_fail_illegal_constructor: { +    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor) +      << (Fn->getPrimaryTemplate() ? 1 : 0); +    MaybeEmitInheritedConstructorNote(S, Fn); +    return; +  } +    case ovl_fail_trivial_conversion:    case ovl_fail_bad_final_conversion:    case ovl_fail_final_conversion_not_exact: @@ -9122,7 +9280,7 @@ void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,    }  } -void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { +static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {    // Desugar the type of the surrogate down to a function type,    // retaining as many typedefs as possible while still showing    // the function type (and, therefore, its parameter types). @@ -9155,10 +9313,9 @@ void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {    MaybeEmitInheritedConstructorNote(S, Cand->Surrogate);  } -void NoteBuiltinOperatorCandidate(Sema &S, -                                  StringRef Opc, -                                  SourceLocation OpLoc, -                                  OverloadCandidate *Cand) { +static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, +                                         SourceLocation OpLoc, +                                         OverloadCandidate *Cand) {    assert(Cand->NumConversions <= 2 && "builtin operator is not binary");    std::string TypeStr("operator");    TypeStr += Opc; @@ -9175,8 +9332,8 @@ void NoteBuiltinOperatorCandidate(Sema &S,    }  } -void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, -                                  OverloadCandidate *Cand) { +static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, +                                         OverloadCandidate *Cand) {    unsigned NoOperands = Cand->NumConversions;    for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {      const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx]; @@ -9228,6 +9385,7 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {    llvm_unreachable("Unhandled deduction result");  } +namespace {  struct CompareOverloadCandidatesForDisplay {    Sema &S;    size_t NumArgs; @@ -9351,11 +9509,12 @@ struct CompareOverloadCandidatesForDisplay {      return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc);    }  }; +}  /// CompleteNonViableCandidate - Normally, overload resolution only  /// computes up to the first. Produces the FixIt set if possible. -void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, -                                ArrayRef<Expr *> Args) { +static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, +                                       ArrayRef<Expr *> Args) {    assert(!Cand->Viable);    // Don't do anything on failures other than bad conversion. @@ -9435,8 +9594,6 @@ void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,    }  } -} // end anonymous namespace -  /// PrintOverloadCandidates - When overload resolution fails, prints  /// diagnostic messages containing the candidates in the candidate  /// set. @@ -9513,6 +9670,7 @@ GetLocationForCandidate(const TemplateSpecCandidate *Cand) {                                : SourceLocation();  } +namespace {  struct CompareTemplateSpecCandidatesForDisplay {    Sema &S;    CompareTemplateSpecCandidatesForDisplay(Sema &S) : S(S) {} @@ -9543,6 +9701,7 @@ struct CompareTemplateSpecCandidatesForDisplay {      return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc);    }  }; +}  /// Diagnose a template argument deduction failure.  /// We are treating these failures as overload failures due to bad @@ -9631,10 +9790,10 @@ QualType Sema::ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType) {    return Ret;  } +namespace {  // A helper class to help with address of function resolution  // - allows us to avoid passing around all those ugly parameters -class AddressOfFunctionResolver  -{ +class AddressOfFunctionResolver {    Sema& S;    Expr* SourceExpr;    const QualType& TargetType;  @@ -9782,12 +9941,12 @@ private:      if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) {        if (S.getLangOpts().CUDA)          if (FunctionDecl *Caller = dyn_cast<FunctionDecl>(S.CurContext)) -          if (S.CheckCUDATarget(Caller, FunDecl)) +          if (!Caller->isImplicit() && S.CheckCUDATarget(Caller, FunDecl))              return false;        // If any candidate has a placeholder return type, trigger its deduction        // now. -      if (S.getLangOpts().CPlusPlus1y && +      if (S.getLangOpts().CPlusPlus14 &&            FunDecl->getReturnType()->isUndeducedType() &&            S.DeduceReturnType(FunDecl, SourceExpr->getLocStart(), Complain))          return false; @@ -9960,7 +10119,8 @@ public:      return &Matches[0].first;    }  }; -   +} +  /// ResolveAddressOfOverloadedFunction - Try to resolve the address of  /// an overloaded function (C++ [over.over]), where @p From is an  /// expression with overloaded function type and @p ToType is the type @@ -10092,7 +10252,7 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,      if (FoundResult) *FoundResult = I.getPair();        } -  if (Matched && getLangOpts().CPlusPlus1y && +  if (Matched && getLangOpts().CPlusPlus14 &&        Matched->getReturnType()->isUndeducedType() &&        DeduceReturnType(Matched, ovl->getExprLoc(), Complain))      return nullptr; @@ -10422,6 +10582,15 @@ public:  } +static std::unique_ptr<CorrectionCandidateCallback> +MakeValidator(Sema &SemaRef, MemberExpr *ME, size_t NumArgs, +              bool HasTemplateArgs, bool AllowTypoCorrection) { +  if (!AllowTypoCorrection) +    return llvm::make_unique<NoTypoCorrectionCCC>(); +  return llvm::make_unique<FunctionCallFilterCCC>(SemaRef, NumArgs, +                                                  HasTemplateArgs, ME); +} +  /// Attempts to recover from a call where no functions were found.  ///  /// Returns true if new candidates were found. @@ -10455,19 +10624,15 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,    LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),                   Sema::LookupOrdinaryName); -  FunctionCallFilterCCC Validator(SemaRef, Args.size(), -                                  ExplicitTemplateArgs != nullptr, -                                  dyn_cast<MemberExpr>(Fn)); -  NoTypoCorrectionCCC RejectAll; -  CorrectionCandidateCallback *CCC = AllowTypoCorrection ? -      (CorrectionCandidateCallback*)&Validator : -      (CorrectionCandidateCallback*)&RejectAll;    if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R,                                OverloadCandidateSet::CSK_Normal,                                ExplicitTemplateArgs, Args) &&        (!EmptyLookup || -       SemaRef.DiagnoseEmptyLookup(S, SS, R, *CCC, -                                   ExplicitTemplateArgs, Args))) +       SemaRef.DiagnoseEmptyLookup( +           S, SS, R, +           MakeValidator(SemaRef, dyn_cast<MemberExpr>(Fn), Args.size(), +                         ExplicitTemplateArgs != nullptr, AllowTypoCorrection), +           ExplicitTemplateArgs, Args)))      return ExprError();    assert(!R.empty() && "lookup results empty despite recovery"); @@ -10945,10 +11110,13 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,    // Add operator candidates that are member functions.    AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet); -  // Add candidates from ADL. -  AddArgumentDependentLookupCandidates(OpName, OpLoc, Args, -                                       /*ExplicitTemplateArgs*/ nullptr, -                                       CandidateSet); +  // Add candidates from ADL. Per [over.match.oper]p2, this lookup is not +  // performed for an assignment operator (nor for operator[] nor operator->, +  // which don't get here). +  if (Opc != BO_Assign) +    AddArgumentDependentLookupCandidates(OpName, OpLoc, Args, +                                         /*ExplicitTemplateArgs*/ nullptr, +                                         CandidateSet);    // Add builtin operator candidates.    AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet); @@ -11031,7 +11199,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,          // Cut off the implicit 'this'.          if (isa<CXXMethodDecl>(FnDecl))            ArgsArray = ArgsArray.slice(1); -        checkCall(FnDecl, ArgsArray, 0, isa<CXXMethodDecl>(FnDecl), OpLoc,  + +        // Check for a self move. +        if (Op == OO_Equal) +          DiagnoseSelfMove(Args[0], Args[1], OpLoc); + +        checkCall(FnDecl, ArgsArray, 0, isa<CXXMethodDecl>(FnDecl), OpLoc,                    TheCall->getSourceRange(), VariadicDoesNotApply);          return MaybeBindToTemporary(TheCall); @@ -11352,6 +11525,10 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,          << (qualsString.find(' ') == std::string::npos ? 1 : 2);      } +    if (resultType->isMemberPointerType()) +      if (Context.getTargetInfo().getCXXABI().isMicrosoft()) +        RequireCompleteType(LParenLoc, resultType, 0); +      CXXMemberCallExpr *call        = new (Context) CXXMemberCallExpr(Context, MemExprE, Args,                                          resultType, valueKind, RParenLoc); @@ -11505,6 +11682,18 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,      new (Context) CXXMemberCallExpr(Context, MemExprE, Args,                                      ResultType, VK, RParenLoc); +  // (CUDA B.1): Check for invalid calls between targets. +  if (getLangOpts().CUDA) { +    if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) { +      if (CheckCUDATarget(Caller, Method)) { +        Diag(MemExpr->getMemberLoc(), diag::err_ref_bad_target) +            << IdentifyCUDATarget(Method) << Method->getIdentifier() +            << IdentifyCUDATarget(Caller); +        return ExprError(); +      } +    } +  } +    // Check for a valid return type.    if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(),                            TheCall, Method)) @@ -11568,7 +11757,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,    if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))      return ExprError(); -  assert(Object.get()->getType()->isRecordType() && "Requires object type argument"); +  assert(Object.get()->getType()->isRecordType() && +         "Requires object type argument");    const RecordType *Record = Object.get()->getType()->getAs<RecordType>();    // C++ [over.call.object]p1: @@ -12272,5 +12462,3 @@ ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,                                                  FunctionDecl *Fn) {    return FixOverloadedFunctionReference(E.get(), Found, Fn);  } - -} // end namespace clang diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index aa3e89ed67a9..5e92d5d07c51 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -406,6 +406,10 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,                                            BinaryOperatorKind opcode,                                            Expr *LHS, Expr *RHS) {    assert(BinaryOperator::isAssignmentOp(opcode)); +   +  // Recover from user error +  if (isa<UnresolvedLookupExpr>(RHS)) +    return ExprError();    Expr *syntacticLHS = rebuildAndCaptureObject(LHS);    OpaqueValueExpr *capturedRHS = capture(RHS); @@ -615,7 +619,7 @@ bool ObjCPropertyOpBuilder::findSetter(bool warn) {      if (setter->isPropertyAccessor() && warn)        if (const ObjCInterfaceDecl *IFace =            dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) { -        const StringRef thisPropertyName(prop->getName()); +        StringRef thisPropertyName = prop->getName();          // Try flipping the case of the first character.          char front = thisPropertyName.front();          front = isLowercase(front) ? toUppercase(front) : toLowercase(front); @@ -1022,7 +1026,8 @@ Sema::ObjCSubscriptKind    // If we don't have a class type in C++, there's no way we can get an    // expression of integral or enumeration type.    const RecordType *RecordTy = T->getAs<RecordType>(); -  if (!RecordTy && T->isObjCObjectPointerType()) +  if (!RecordTy && +      (T->isObjCObjectPointerType() || T->isVoidPointerType()))      // All other scalar cases are assumed to be dictionary indexing which      // caller handles, with diagnostics if needed.      return OS_Dictionary; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 278e6d66828b..22ed93082065 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -19,6 +19,7 @@  #include "clang/AST/EvaluatedExprVisitor.h"  #include "clang/AST/ExprCXX.h"  #include "clang/AST/ExprObjC.h" +#include "clang/AST/RecursiveASTVisitor.h"  #include "clang/AST/StmtCXX.h"  #include "clang/AST/StmtObjC.h"  #include "clang/AST/TypeLoc.h" @@ -184,6 +185,12 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {    const Expr *E = dyn_cast_or_null<Expr>(S);    if (!E)      return; + +  // If we are in an unevaluated expression context, then there can be no unused +  // results because the results aren't expected to be used in the first place. +  if (isUnevaluatedContext()) +    return; +    SourceLocation ExprLoc = E->IgnoreParens()->getExprLoc();    // In most cases, we don't want to warn if the expression is written in a    // macro body, or if the macro comes from a system header. If the offending @@ -364,6 +371,23 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,      return StmtError();    } +  ExprResult LHS = +      CorrectDelayedTyposInExpr(LHSVal, [this](class Expr *E) { +        if (!getLangOpts().CPlusPlus11) +          return VerifyIntegerConstantExpression(E); +        if (Expr *CondExpr = +                getCurFunction()->SwitchStack.back()->getCond()) { +          QualType CondType = CondExpr->getType(); +          llvm::APSInt TempVal; +          return CheckConvertedConstantExpression(E, CondType, TempVal, +                                                        CCEK_CaseValue); +        } +        return ExprError(); +      }); +  if (LHS.isInvalid()) +    return StmtError(); +  LHSVal = LHS.get(); +    if (!getLangOpts().CPlusPlus11) {      // C99 6.8.4.2p3: The expression shall be an integer constant.      // However, GCC allows any evaluatable integer expression. @@ -381,14 +405,19 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,      }    } -  LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false, -                               getLangOpts().CPlusPlus11).get(); -  if (RHSVal) -    RHSVal = ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false, -                                 getLangOpts().CPlusPlus11).get(); +  LHS = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false, +                                 getLangOpts().CPlusPlus11); +  if (LHS.isInvalid()) +    return StmtError(); + +  auto RHS = RHSVal ? ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false, +                                          getLangOpts().CPlusPlus11) +                    : ExprResult(); +  if (RHS.isInvalid()) +    return StmtError(); -  CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc, -                                        ColonLoc); +  CaseStmt *CS = new (Context) +      CaseStmt(LHS.get(), RHS.get(), CaseLoc, DotDotDotLoc, ColonLoc);    getCurFunction()->SwitchStack.back()->addSwitchCase(CS);    return CS;  } @@ -431,7 +460,11 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,    TheDecl->setStmt(LS);    if (!TheDecl->isGnuLocal()) {      TheDecl->setLocStart(IdentLoc); -    TheDecl->setLocation(IdentLoc); +    if (!TheDecl->isMSAsmLabel()) { +      // Don't update the location of MS ASM labels.  These will result in +      // a diagnostic, and changing the location here will mess that up. +      TheDecl->setLocation(IdentLoc); +    }    }    return LS;  } @@ -481,47 +514,6 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,                                thenStmt, ElseLoc, elseStmt);  } -/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have -/// the specified width and sign.  If an overflow occurs, detect it and emit -/// the specified diagnostic. -void Sema::ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &Val, -                                              unsigned NewWidth, bool NewSign, -                                              SourceLocation Loc, -                                              unsigned DiagID) { -  // Perform a conversion to the promoted condition type if needed. -  if (NewWidth > Val.getBitWidth()) { -    // If this is an extension, just do it. -    Val = Val.extend(NewWidth); -    Val.setIsSigned(NewSign); - -    // If the input was signed and negative and the output is -    // unsigned, don't bother to warn: this is implementation-defined -    // behavior. -    // FIXME: Introduce a second, default-ignored warning for this case? -  } else if (NewWidth < Val.getBitWidth()) { -    // If this is a truncation, check for overflow. -    llvm::APSInt ConvVal(Val); -    ConvVal = ConvVal.trunc(NewWidth); -    ConvVal.setIsSigned(NewSign); -    ConvVal = ConvVal.extend(Val.getBitWidth()); -    ConvVal.setIsSigned(Val.isSigned()); -    if (ConvVal != Val) -      Diag(Loc, DiagID) << Val.toString(10) << ConvVal.toString(10); - -    // Regardless of whether a diagnostic was emitted, really do the -    // truncation. -    Val = Val.trunc(NewWidth); -    Val.setIsSigned(NewSign); -  } else if (NewSign != Val.isSigned()) { -    // Convert the sign to match the sign of the condition.  This can cause -    // overflow as well: unsigned(INTMIN) -    // We don't diagnose this overflow, because it is implementation-defined -    // behavior. -    // FIXME: Introduce a second, default-ignored warning for this case? -    Val.setIsSigned(NewSign); -  } -} -  namespace {    struct CaseCompareFunctor {      bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS, @@ -671,33 +663,63 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,  }  static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) { -  if (Val.getBitWidth() < BitWidth) -    Val = Val.extend(BitWidth); -  else if (Val.getBitWidth() > BitWidth) -    Val = Val.trunc(BitWidth); +  Val = Val.extOrTrunc(BitWidth);    Val.setIsSigned(IsSigned);  } +/// Check the specified case value is in range for the given unpromoted switch +/// type. +static void checkCaseValue(Sema &S, SourceLocation Loc, const llvm::APSInt &Val, +                           unsigned UnpromotedWidth, bool UnpromotedSign) { +  // If the case value was signed and negative and the switch expression is +  // unsigned, don't bother to warn: this is implementation-defined behavior. +  // FIXME: Introduce a second, default-ignored warning for this case? +  if (UnpromotedWidth < Val.getBitWidth()) { +    llvm::APSInt ConvVal(Val); +    AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign); +    AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned()); +    // FIXME: Use different diagnostics for overflow  in conversion to promoted +    // type versus "switch expression cannot have this value". Use proper +    // IntRange checking rather than just looking at the unpromoted type here. +    if (ConvVal != Val) +      S.Diag(Loc, diag::warn_case_value_overflow) << Val.toString(10) +                                                  << ConvVal.toString(10); +  } +} + +typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64> EnumValsTy; +  /// Returns true if we should emit a diagnostic about this case expression not  /// being a part of the enum used in the switch controlling expression. -static bool ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext &Ctx, +static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S,                                                const EnumDecl *ED, -                                              const Expr *CaseExpr) { -  // Don't warn if the 'case' expression refers to a static const variable of -  // the enum type. -  CaseExpr = CaseExpr->IgnoreParenImpCasts(); -  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr)) { +                                              const Expr *CaseExpr, +                                              EnumValsTy::iterator &EI, +                                              EnumValsTy::iterator &EIEnd, +                                              const llvm::APSInt &Val) { +  bool FlagType = ED->hasAttr<FlagEnumAttr>(); + +  if (const DeclRefExpr *DRE = +          dyn_cast<DeclRefExpr>(CaseExpr->IgnoreParenImpCasts())) {      if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { -      if (!VD->hasGlobalStorage()) -        return true;        QualType VarType = VD->getType(); -      if (!VarType.isConstQualified()) -        return true; -      QualType EnumType = Ctx.getTypeDeclType(ED); -      if (Ctx.hasSameUnqualifiedType(EnumType, VarType)) +      QualType EnumType = S.Context.getTypeDeclType(ED); +      if (VD->hasGlobalStorage() && VarType.isConstQualified() && +          S.Context.hasSameUnqualifiedType(EnumType, VarType))          return false;      }    } + +  if (FlagType) { +    return !S.IsValueInFlagEnum(ED, Val, false); +  } else { +    while (EI != EIEnd && EI->first < Val) +      EI++; + +    if (EI != EIEnd && EI->first == Val) +      return false; +  } +    return true;  } @@ -708,9 +730,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,    assert(SS == getCurFunction()->SwitchStack.back() &&           "switch stack missing push/pop!"); +  getCurFunction()->SwitchStack.pop_back(); +    if (!BodyStmt) return StmtError();    SS->setBody(BodyStmt, SwitchLoc); -  getCurFunction()->SwitchStack.pop_back();    Expr *CondExpr = SS->getCond();    if (!CondExpr) return StmtError(); @@ -744,13 +767,20 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,      }    } -  // Get the bitwidth of the switched-on value before promotions.  We must +  // Get the bitwidth of the switched-on value after promotions. We must    // convert the integer case values to this width before comparison.    bool HasDependentValue      = CondExpr->isTypeDependent() || CondExpr->isValueDependent(); -  unsigned CondWidth +  unsigned CondWidth = HasDependentValue ? 0 : Context.getIntWidth(CondType); +  bool CondIsSigned = CondType->isSignedIntegerOrEnumerationType(); + +  // Get the width and signedness that the condition might actually have, for +  // warning purposes. +  // FIXME: Grab an IntRange for the condition rather than using the unpromoted +  // type. +  unsigned CondWidthBeforePromotion      = HasDependentValue ? 0 : Context.getIntWidth(CondTypeBeforePromotion); -  bool CondIsSigned +  bool CondIsSignedBeforePromotion      = CondTypeBeforePromotion->isSignedIntegerOrEnumerationType();    // Accumulate all of the case values in a vector so that we can sort them @@ -816,15 +846,13 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,          Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).get();        } -      // Convert the value to the same width/sign as the condition had prior to -      // integral promotions. -      // -      // FIXME: This causes us to reject valid code: -      //   switch ((char)c) { case 256: case 0: return 0; } -      // Here we claim there is a duplicated condition value, but there is not. -      ConvertIntegerToTypeWarnOnOverflow(LoVal, CondWidth, CondIsSigned, -                                         Lo->getLocStart(), -                                         diag::warn_case_value_overflow); +      // Check the unconverted value is within the range of possible values of +      // the switch expression. +      checkCaseValue(*this, Lo->getLocStart(), LoVal, +                     CondWidthBeforePromotion, CondIsSignedBeforePromotion); + +      // Convert the value to the same width/sign as the condition. +      AdjustAPSInt(LoVal, CondWidth, CondIsSigned);        CS->setLHS(Lo); @@ -847,9 +875,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,      llvm::APSInt ConstantCondValue;      bool HasConstantCond = false;      if (!HasDependentValue && !TheDefaultStmt) { -      HasConstantCond -        = CondExprBeforePromotion->EvaluateAsInt(ConstantCondValue, Context, -                                                 Expr::SE_AllowSideEffects); +      HasConstantCond = CondExpr->EvaluateAsInt(ConstantCondValue, Context, +                                                Expr::SE_AllowSideEffects);        assert(!HasConstantCond ||               (ConstantCondValue.getBitWidth() == CondWidth &&                ConstantCondValue.isSigned() == CondIsSigned)); @@ -935,10 +962,13 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,            Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).get();          } +        // Check the unconverted value is within the range of possible values of +        // the switch expression. +        checkCaseValue(*this, Hi->getLocStart(), HiVal, +                       CondWidthBeforePromotion, CondIsSignedBeforePromotion); +          // Convert the value to the same width/sign as the condition. -        ConvertIntegerToTypeWarnOnOverflow(HiVal, CondWidth, CondIsSigned, -                                           Hi->getLocStart(), -                                           diag::warn_case_value_overflow); +        AdjustAPSInt(HiVal, CondWidth, CondIsSigned);          CR->setRHS(Hi); @@ -1029,8 +1059,6 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,      // If switch has default case, then ignore it.      if (!CaseListIsErroneous  && !HasConstantCond && ET) {        const EnumDecl *ED = ET->getDecl(); -      typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64> -        EnumValsTy;        EnumValsTy EnumVals;        // Gather all enum values, set their type and sort them, @@ -1041,57 +1069,48 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,          EnumVals.push_back(std::make_pair(Val, EDI));        }        std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals); -      EnumValsTy::iterator EIend = +      auto EI = EnumVals.begin(), EIEnd =          std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);        // See which case values aren't in enum. -      EnumValsTy::const_iterator EI = EnumVals.begin();        for (CaseValsTy::const_iterator CI = CaseVals.begin(); -           CI != CaseVals.end(); CI++) { -        while (EI != EIend && EI->first < CI->first) -          EI++; -        if (EI == EIend || EI->first > CI->first) { -          Expr *CaseExpr = CI->second->getLHS(); -          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr)) -            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum) -              << CondTypeBeforePromotion; -        } +          CI != CaseVals.end(); CI++) { +        Expr *CaseExpr = CI->second->getLHS(); +        if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd, +                                              CI->first)) +          Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum) +            << CondTypeBeforePromotion;        } +        // See which of case ranges aren't in enum        EI = EnumVals.begin();        for (CaseRangesTy::const_iterator RI = CaseRanges.begin(); -           RI != CaseRanges.end() && EI != EIend; RI++) { -        while (EI != EIend && EI->first < RI->first) -          EI++; - -        if (EI == EIend || EI->first != RI->first) { -          Expr *CaseExpr = RI->second->getLHS(); -          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr)) -            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum) -              << CondTypeBeforePromotion; -        } +          RI != CaseRanges.end(); RI++) { +        Expr *CaseExpr = RI->second->getLHS(); +        if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd, +                                              RI->first)) +          Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum) +            << CondTypeBeforePromotion;          llvm::APSInt Hi =            RI->second->getRHS()->EvaluateKnownConstInt(Context);          AdjustAPSInt(Hi, CondWidth, CondIsSigned); -        while (EI != EIend && EI->first < Hi) -          EI++; -        if (EI == EIend || EI->first != Hi) { -          Expr *CaseExpr = RI->second->getRHS(); -          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr)) -            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum) -              << CondTypeBeforePromotion; -        } + +        CaseExpr = RI->second->getRHS(); +        if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd, +                                              Hi)) +          Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum) +            << CondTypeBeforePromotion;        }        // Check which enum vals aren't in switch -      CaseValsTy::const_iterator CI = CaseVals.begin(); -      CaseRangesTy::const_iterator RI = CaseRanges.begin(); +      auto CI = CaseVals.begin(); +      auto RI = CaseRanges.begin();        bool hasCasesNotInSwitch = false;        SmallVector<DeclarationName,8> UnhandledNames; -      for (EI = EnumVals.begin(); EI != EIend; EI++){ +      for (EI = EnumVals.begin(); EI != EIEnd; EI++){          // Drop unneeded case values          while (CI != CaseVals.end() && CI->first < EI->first)            CI++; @@ -1178,30 +1197,37 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,          llvm::APSInt RhsVal = SrcExpr->EvaluateKnownConstInt(Context);          AdjustAPSInt(RhsVal, DstWidth, DstIsSigned);          const EnumDecl *ED = ET->getDecl(); -        typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64> -            EnumValsTy; -        EnumValsTy EnumVals; - -        // Gather all enum values, set their type and sort them, -        // allowing easier comparison with rhs constant. -        for (auto *EDI : ED->enumerators()) { -          llvm::APSInt Val = EDI->getInitVal(); -          AdjustAPSInt(Val, DstWidth, DstIsSigned); -          EnumVals.push_back(std::make_pair(Val, EDI)); -        } -        if (EnumVals.empty()) -          return; -        std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals); -        EnumValsTy::iterator EIend = -            std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); - -        // See which values aren't in the enum. -        EnumValsTy::const_iterator EI = EnumVals.begin(); -        while (EI != EIend && EI->first < RhsVal) -          EI++; -        if (EI == EIend || EI->first != RhsVal) { -          Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment) + +        if (ED->hasAttr<FlagEnumAttr>()) { +          if (!IsValueInFlagEnum(ED, RhsVal, true)) +            Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)                << DstType.getUnqualifiedType(); +        } else { +          typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64> +              EnumValsTy; +          EnumValsTy EnumVals; + +          // Gather all enum values, set their type and sort them, +          // allowing easier comparison with rhs constant. +          for (auto *EDI : ED->enumerators()) { +            llvm::APSInt Val = EDI->getInitVal(); +            AdjustAPSInt(Val, DstWidth, DstIsSigned); +            EnumVals.push_back(std::make_pair(Val, EDI)); +          } +          if (EnumVals.empty()) +            return; +          std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals); +          EnumValsTy::iterator EIend = +              std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); + +          // See which values aren't in the enum. +          EnumValsTy::const_iterator EI = EnumVals.begin(); +          while (EI != EIend && EI->first < RhsVal) +            EI++; +          if (EI == EIend || EI->first != RhsVal) { +            Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment) +                << DstType.getUnqualifiedType(); +          }          }        }      } @@ -1260,13 +1286,13 @@ namespace {    // the evaluated decls into a vector.  Simple is set to true if none    // of the excluded constructs are used.    class DeclExtractor : public EvaluatedExprVisitor<DeclExtractor> { -    llvm::SmallPtrSet<VarDecl*, 8> &Decls; +    llvm::SmallPtrSetImpl<VarDecl*> &Decls;      SmallVectorImpl<SourceRange> &Ranges;      bool Simple;    public:      typedef EvaluatedExprVisitor<DeclExtractor> Inherited; -    DeclExtractor(Sema &S, llvm::SmallPtrSet<VarDecl*, 8> &Decls, +    DeclExtractor(Sema &S, llvm::SmallPtrSetImpl<VarDecl*> &Decls,                    SmallVectorImpl<SourceRange> &Ranges) :          Inherited(S.Context),          Decls(Decls), @@ -1338,13 +1364,13 @@ namespace {    // DeclMatcher checks to see if the decls are used in a non-evauluated    // context.    class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> { -    llvm::SmallPtrSet<VarDecl*, 8> &Decls; +    llvm::SmallPtrSetImpl<VarDecl*> &Decls;      bool FoundDecl;    public:      typedef EvaluatedExprVisitor<DeclMatcher> Inherited; -    DeclMatcher(Sema &S, llvm::SmallPtrSet<VarDecl*, 8> &Decls, +    DeclMatcher(Sema &S, llvm::SmallPtrSetImpl<VarDecl*> &Decls,                  Stmt *Statement) :          Inherited(S.Context), Decls(Decls), FoundDecl(false) {        if (!Statement) return; @@ -1427,8 +1453,8 @@ namespace {      if (Decls.size() == 0) return;      // Don't warn on volatile, static, or global variables. -    for (llvm::SmallPtrSet<VarDecl*, 8>::iterator I = Decls.begin(), -                                                  E = Decls.end(); +    for (llvm::SmallPtrSetImpl<VarDecl*>::iterator I = Decls.begin(), +                                                   E = Decls.end();           I != E; ++I)        if ((*I)->getType().isVolatileQualified() ||            (*I)->hasGlobalStorage()) return; @@ -1443,8 +1469,8 @@ namespace {        PDiag << 0;      else {        PDiag << Decls.size(); -      for (llvm::SmallPtrSet<VarDecl*, 8>::iterator I = Decls.begin(), -                                                    E = Decls.end(); +      for (llvm::SmallPtrSetImpl<VarDecl*>::iterator I = Decls.begin(), +                                                     E = Decls.end();             I != E; ++I)          PDiag << (*I)->getDeclName();      } @@ -1660,11 +1686,16 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {    if (!collection)      return ExprError(); +  ExprResult result = CorrectDelayedTyposInExpr(collection); +  if (!result.isUsable()) +    return ExprError(); +  collection = result.get(); +    // Bail out early if we've got a type-dependent expression.    if (collection->isTypeDependent()) return collection;    // Perform normal l-value conversion. -  ExprResult result = DefaultFunctionArrayLvalueConversion(collection); +  result = DefaultFunctionArrayLvalueConversion(collection);    if (result.isInvalid())      return ExprError();    collection = result.get(); @@ -2453,7 +2484,7 @@ VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,    // - in a return statement in a function [where] ...    // ... the expression is the name of a non-volatile automatic object ...    DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens()); -  if (!DR || DR->refersToEnclosingLocal()) +  if (!DR || DR->refersToEnclosingVariableOrCapture())      return nullptr;    VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());    if (!VD) @@ -2621,8 +2652,12 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {          return StmtError();        RetValExp = Result.get(); +      // DR1048: even prior to C++14, we should use the 'auto' deduction rules +      // when deducing a return type for a lambda-expression (or by extension +      // for a block). These rules differ from the stated C++11 rules only in +      // that they remove top-level cv-qualifiers.        if (!CurContext->isDependentContext()) -        FnRetType = RetValExp->getType(); +        FnRetType = RetValExp->getType().getUnqualifiedType();        else          FnRetType = CurCap->ReturnType = Context.DependentTy;      } else { @@ -2727,14 +2762,54 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {    return Result;  } +namespace { +/// \brief Marks all typedefs in all local classes in a type referenced. +/// +/// In a function like +/// auto f() { +///   struct S { typedef int a; }; +///   return S(); +/// } +/// +/// the local type escapes and could be referenced in some TUs but not in +/// others. Pretend that all local typedefs are always referenced, to not warn +/// on this. This isn't necessary if f has internal linkage, or the typedef +/// is private. +class LocalTypedefNameReferencer +    : public RecursiveASTVisitor<LocalTypedefNameReferencer> { +public: +  LocalTypedefNameReferencer(Sema &S) : S(S) {} +  bool VisitRecordType(const RecordType *RT); +private: +  Sema &S; +}; +bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) { +  auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl()); +  if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() || +      R->isDependentType()) +    return true; +  for (auto *TmpD : R->decls()) +    if (auto *T = dyn_cast<TypedefNameDecl>(TmpD)) +      if (T->getAccess() != AS_private || R->hasFriends()) +        S.MarkAnyDeclReferenced(T->getLocation(), T, /*OdrUse=*/false); +  return true; +} +} + +TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const { +  TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); +  while (auto ATL = TL.getAs<AttributedTypeLoc>()) +    TL = ATL.getModifiedLoc().IgnoreParens(); +  return TL.castAs<FunctionProtoTypeLoc>().getReturnLoc(); +} +  /// Deduce the return type for a function from a returned expression, per  /// C++1y [dcl.spec.auto]p6.  bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,                                              SourceLocation ReturnLoc,                                              Expr *&RetExpr,                                              AutoType *AT) { -  TypeLoc OrigResultType = FD->getTypeSourceInfo()->getTypeLoc(). -    IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc(); +  TypeLoc OrigResultType = getReturnTypeLoc(FD);    QualType Deduced;    if (RetExpr && isa<InitListExpr>(RetExpr)) { @@ -2772,6 +2847,11 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,      if (DAR != DAR_Succeeded)        return true; + +    // If a local type is part of the returned type, mark its fields as +    // referenced. +    LocalTypedefNameReferencer Referencer(*this); +    Referencer.TraverseType(RetExpr->getType());    } else {      //  In the case of a return with no operand, the initializer is considered      //  to be void(). @@ -2872,7 +2952,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {    // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing    // deduction. -  if (getLangOpts().CPlusPlus1y) { +  if (getLangOpts().CPlusPlus14) {      if (AutoType *AT = FnRetType->getContainedAutoType()) {        FunctionDecl *FD = cast<FunctionDecl>(CurContext);        if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { @@ -2964,14 +3044,26 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {      Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);    } else if (!RetValExp && !HasDependentReturnType) { -    unsigned DiagID = diag::warn_return_missing_expr;  // C90 6.6.6.4p4 -    // C99 6.8.6.4p1 (ext_ since GCC warns) -    if (getLangOpts().C99) DiagID = diag::ext_return_missing_expr; +    FunctionDecl *FD = getCurFunctionDecl(); -    if (FunctionDecl *FD = getCurFunctionDecl()) +    unsigned DiagID; +    if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) { +      // C++11 [stmt.return]p2 +      DiagID = diag::err_constexpr_return_missing_expr; +      FD->setInvalidDecl(); +    } else if (getLangOpts().C99) { +      // C99 6.8.6.4p1 (ext_ since GCC warns) +      DiagID = diag::ext_return_missing_expr; +    } else { +      // C90 6.6.6.4p4 +      DiagID = diag::warn_return_missing_expr; +    } + +    if (FD)        Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/;      else        Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/; +      Result = new (Context) ReturnStmt(ReturnLoc);    } else {      assert(RetValExp || HasDependentReturnType); @@ -3119,9 +3211,24 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {    if (!type->isDependentType() &&        !type->isObjCObjectPointerType()) {      const PointerType *pointerType = type->getAs<PointerType>(); -    if (!pointerType || !pointerType->getPointeeType()->isVoidType()) -      return Diag(atLoc, diag::error_objc_synchronized_expects_object) -               << type << operand->getSourceRange(); +    if (!pointerType || !pointerType->getPointeeType()->isVoidType()) { +      if (getLangOpts().CPlusPlus) { +        if (RequireCompleteType(atLoc, type, +                                diag::err_incomplete_receiver_type)) +          return Diag(atLoc, diag::error_objc_synchronized_expects_object) +                   << type << operand->getSourceRange(); + +        ExprResult result = PerformContextuallyConvertToObjCPointer(operand); +        if (!result.isUsable()) +          return Diag(atLoc, diag::error_objc_synchronized_expects_object) +                   << type << operand->getSourceRange(); + +        operand = result.get(); +      } else { +          return Diag(atLoc, diag::error_objc_synchronized_expects_object) +                   << type << operand->getSourceRange(); +      } +    }    }    // The operand to @synchronized is a full-expression. @@ -3249,15 +3356,16 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,    return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);  } -StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, -                                  Stmt *TryBlock, Stmt *Handler, -                                  int HandlerIndex, int HandlerParentIndex) { +StmtResult +Sema::ActOnSEHTryBlock(bool IsCXXTry, +                       SourceLocation TryLoc, +                       Stmt *TryBlock, +                       Stmt *Handler) {    assert(TryBlock && Handler);    getCurFunction()->setHasBranchProtectedScope(); -  return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler, -                            HandlerIndex, HandlerParentIndex); +  return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler);  }  StmtResult @@ -3330,6 +3438,7 @@ Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,    else      RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/nullptr); +  RD->setCapturedRecord();    DC->addDecl(RD);    RD->setImplicit();    RD->startDefinition(); @@ -3353,6 +3462,11 @@ static void buildCapturedStmtCaptureList(                                                 CapturedStmt::VCK_This));        CaptureInits.push_back(Cap->getInitExpr());        continue; +    } else if (Cap->isVLATypeCapture()) { +      Captures.push_back( +          CapturedStmt::Capture(Cap->getLocation(), CapturedStmt::VCK_VLAType)); +      CaptureInits.push_back(nullptr); +      continue;      }      assert(Cap->isReferenceCapture() && diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 5d076cac940f..286c7619ed40 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -15,6 +15,7 @@  #include "clang/AST/RecordLayout.h"  #include "clang/AST/TypeLoc.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/Lex/Preprocessor.h"  #include "clang/Sema/Initialization.h"  #include "clang/Sema/Lookup.h"  #include "clang/Sema/Scope.h" @@ -74,6 +75,32 @@ static bool isOperandMentioned(unsigned OpNo,    return false;  } +static bool CheckNakedParmReference(Expr *E, Sema &S) { +  FunctionDecl *Func = dyn_cast<FunctionDecl>(S.CurContext); +  if (!Func) +    return false; +  if (!Func->hasAttr<NakedAttr>()) +    return false; + +  SmallVector<Expr*, 4> WorkList; +  WorkList.push_back(E); +  while (WorkList.size()) { +    Expr *E = WorkList.pop_back_val(); +    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { +      if (isa<ParmVarDecl>(DRE->getDecl())) { +        S.Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref); +        S.Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute); +        return true; +      } +    } +    for (Stmt *Child : E->children()) { +      if (Expr *E = dyn_cast_or_null<Expr>(Child)) +        WorkList.push_back(E); +    } +  } +  return false; +} +  StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,                                   bool IsVolatile, unsigned NumOutputs,                                   unsigned NumInputs, IdentifierInfo **Names, @@ -89,15 +116,11 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,    SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;    // The parser verifies that there is a string literal here. -  if (!AsmString->isAscii()) -    return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character) -      << AsmString->getSourceRange()); +  assert(AsmString->isAscii());    for (unsigned i = 0; i != NumOutputs; i++) {      StringLiteral *Literal = Constraints[i]; -    if (!Literal->isAscii()) -      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) -        << Literal->getSourceRange()); +    assert(Literal->isAscii());      StringRef OutputName;      if (Names[i]) @@ -109,27 +132,69 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,                              diag::err_asm_invalid_output_constraint)                         << Info.getConstraintStr()); +    ExprResult ER = CheckPlaceholderExpr(Exprs[i]); +    if (ER.isInvalid()) +      return StmtError(); +    Exprs[i] = ER.get(); +      // Check that the output exprs are valid lvalues.      Expr *OutputExpr = Exprs[i]; -    if (CheckAsmLValue(OutputExpr, *this)) -      return StmtError(Diag(OutputExpr->getLocStart(), -                            diag::err_asm_invalid_lvalue_in_output) -                       << OutputExpr->getSourceRange()); -    if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(), -                            diag::err_dereference_incomplete_type)) +    // Referring to parameters is not allowed in naked functions. +    if (CheckNakedParmReference(OutputExpr, *this))        return StmtError();      OutputConstraintInfos.push_back(Info); + +    // If this is dependent, just continue. +    if (OutputExpr->isTypeDependent()) +      continue; + +    Expr::isModifiableLvalueResult IsLV = +        OutputExpr->isModifiableLvalue(Context, /*Loc=*/nullptr); +    switch (IsLV) { +    case Expr::MLV_Valid: +      // Cool, this is an lvalue. +      break; +    case Expr::MLV_ArrayType: +      // This is OK too. +      break; +    case Expr::MLV_LValueCast: { +      const Expr *LVal = OutputExpr->IgnoreParenNoopCasts(Context); +      if (!getLangOpts().HeinousExtensions) { +        Diag(LVal->getLocStart(), diag::err_invalid_asm_cast_lvalue) +            << OutputExpr->getSourceRange(); +      } else { +        Diag(LVal->getLocStart(), diag::warn_invalid_asm_cast_lvalue) +            << OutputExpr->getSourceRange(); +      } +      // Accept, even if we emitted an error diagnostic. +      break; +    } +    case Expr::MLV_IncompleteType: +    case Expr::MLV_IncompleteVoidType: +      if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(), +                              diag::err_dereference_incomplete_type)) +        return StmtError(); +    default: +      return StmtError(Diag(OutputExpr->getLocStart(), +                            diag::err_asm_invalid_lvalue_in_output) +                       << OutputExpr->getSourceRange()); +    } + +    unsigned Size = Context.getTypeSize(OutputExpr->getType()); +    if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), +                                                    Size)) +      return StmtError(Diag(OutputExpr->getLocStart(), +                            diag::err_asm_invalid_output_size) +                       << Info.getConstraintStr());    }    SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;    for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {      StringLiteral *Literal = Constraints[i]; -    if (!Literal->isAscii()) -      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) -        << Literal->getSourceRange()); +    assert(Literal->isAscii());      StringRef InputName;      if (Names[i]) @@ -143,8 +208,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,                         << Info.getConstraintStr());      } +    ExprResult ER = CheckPlaceholderExpr(Exprs[i]); +    if (ER.isInvalid()) +      return StmtError(); +    Exprs[i] = ER.get(); +      Expr *InputExpr = Exprs[i]; +    // Referring to parameters is not allowed in naked functions. +    if (CheckNakedParmReference(InputExpr, *this)) +      return StmtError(); +      // Only allow void types for memory constraints.      if (Info.allowsMemory() && !Info.allowsRegister()) {        if (CheckAsmLValue(InputExpr, *this)) @@ -152,6 +226,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,                                diag::err_asm_invalid_lvalue_in_input)                           << Info.getConstraintStr()                           << InputExpr->getSourceRange()); +    } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { +      llvm::APSInt Result; +      if (!InputExpr->EvaluateAsInt(Result, Context)) +        return StmtError( +            Diag(InputExpr->getLocStart(), diag::err_asm_invalid_type_in_input) +            << InputExpr->getType() << Info.getConstraintStr() +            << InputExpr->getSourceRange()); +      if (Result.slt(Info.getImmConstantMin()) || +          Result.sgt(Info.getImmConstantMax())) +        return StmtError(Diag(InputExpr->getLocStart(), +                              diag::err_invalid_asm_value_for_constraint) +                         << Result.toString(10) << Info.getConstraintStr() +                         << InputExpr->getSourceRange()); +      } else {        ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);        if (Result.isInvalid()) @@ -191,9 +279,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,    // Check that the clobbers are valid.    for (unsigned i = 0; i != NumClobbers; i++) {      StringLiteral *Literal = Clobbers[i]; -    if (!Literal->isAscii()) -      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) -        << Literal->getSourceRange()); +    assert(Literal->isAscii());      StringRef Clobber = Literal->getString(); @@ -257,16 +343,47 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,        continue;      unsigned Size = Context.getTypeSize(Ty); -    if (!Context.getTargetInfo() -          .validateConstraintModifier(Literal->getString(), Piece.getModifier(), -                                      Size)) +    std::string SuggestedModifier; +    if (!Context.getTargetInfo().validateConstraintModifier( +            Literal->getString(), Piece.getModifier(), Size, +            SuggestedModifier)) {        Diag(Exprs[ConstraintIdx]->getLocStart(),             diag::warn_asm_mismatched_size_modifier); + +      if (!SuggestedModifier.empty()) { +        auto B = Diag(Piece.getRange().getBegin(), +                      diag::note_asm_missing_constraint_modifier) +                 << SuggestedModifier; +        SuggestedModifier = "%" + SuggestedModifier + Piece.getString(); +        B.AddFixItHint(FixItHint::CreateReplacement(Piece.getRange(), +                                                    SuggestedModifier)); +      } +    }    }    // Validate tied input operands for type mismatches. +  unsigned NumAlternatives = ~0U; +  for (unsigned i = 0, e = OutputConstraintInfos.size(); i != e; ++i) { +    TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; +    StringRef ConstraintStr = Info.getConstraintStr(); +    unsigned AltCount = ConstraintStr.count(',') + 1; +    if (NumAlternatives == ~0U) +      NumAlternatives = AltCount; +    else if (NumAlternatives != AltCount) +      return StmtError(Diag(NS->getOutputExpr(i)->getLocStart(), +                            diag::err_asm_unexpected_constraint_alternatives) +                       << NumAlternatives << AltCount); +  }    for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {      TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; +    StringRef ConstraintStr = Info.getConstraintStr(); +    unsigned AltCount = ConstraintStr.count(',') + 1; +    if (NumAlternatives == ~0U) +      NumAlternatives = AltCount; +    else if (NumAlternatives != AltCount) +      return StmtError(Diag(NS->getInputExpr(i)->getLocStart(), +                            diag::err_asm_unexpected_constraint_alternatives) +                       << NumAlternatives << AltCount);      // If this is a tied constraint, verify that the output and input have      // either exactly the same type, or that they are int/ptr operands with the @@ -394,6 +511,10 @@ ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,    Result = CheckPlaceholderExpr(Result.get());    if (!Result.isUsable()) return Result; +  // Referring to parameters is not allowed in naked functions. +  if (CheckNakedParmReference(Result.get(), *this)) +    return ExprError(); +    QualType T = Result.get()->getType();    // For now, reject dependent types. @@ -443,9 +564,10 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,    NamedDecl *FoundDecl = BaseResult.getFoundDecl();    if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl))      RT = VD->getType()->getAs<RecordType>(); -  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl)) +  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl)) { +    MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);      RT = TD->getUnderlyingType()->getAs<RecordType>(); -  else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) +  } else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl))      RT = TD->getTypeForDecl()->getAs<RecordType>();    if (!RT)      return true; @@ -481,6 +603,7 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,                                  ArrayRef<Expr*> Exprs,                                  SourceLocation EndLoc) {    bool IsSimple = (NumOutputs != 0 || NumInputs != 0); +  getCurFunction()->setHasBranchProtectedScope();    MSAsmStmt *NS =      new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,                              /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs, @@ -488,3 +611,34 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,                              Clobbers, EndLoc);    return NS;  } + +LabelDecl *Sema::GetOrCreateMSAsmLabel(StringRef ExternalLabelName, +                                       SourceLocation Location, +                                       bool AlwaysCreate) { +  LabelDecl* Label = LookupOrCreateLabel(PP.getIdentifierInfo(ExternalLabelName), +                                         Location); + +  if (Label->isMSAsmLabel()) { +    // If we have previously created this label implicitly, mark it as used. +    Label->markUsed(Context); +  } else { +    // Otherwise, insert it, but only resolve it if we have seen the label itself. +    std::string InternalName; +    llvm::raw_string_ostream OS(InternalName); +    // Create an internal name for the label.  The name should not be a valid mangled +    // name, and should be unique.  We use a dot to make the name an invalid mangled +    // name. +    OS << "__MSASMLABEL_." << MSAsmLabelNameCounter++ << "__" << ExternalLabelName; +    Label->setMSAsmLabel(OS.str()); +  } +  if (AlwaysCreate) { +    // The label might have been created implicitly from a previously encountered +    // goto statement.  So, for both newly created and looked up labels, we mark +    // them as resolved. +    Label->setMSAsmLabelResolved(); +  } +  // Adjust their location for being able to generate accurate diagnostics. +  Label->setLocation(Location); + +  return Label; +} diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp index a32e0fbcb622..19e2c8ed652f 100644 --- a/lib/Sema/SemaStmtAttr.cpp +++ b/lib/Sema/SemaStmtAttr.cpp @@ -47,30 +47,36 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,                                  SourceRange) {    IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0);    IdentifierLoc *OptionLoc = A.getArgAsIdent(1); -  IdentifierInfo *OptionInfo = OptionLoc->Ident; -  IdentifierLoc *ValueLoc = A.getArgAsIdent(2); -  IdentifierInfo *ValueInfo = ValueLoc ? ValueLoc->Ident : nullptr; +  IdentifierLoc *StateLoc = A.getArgAsIdent(2);    Expr *ValueExpr = A.getArgAsExpr(3); -  assert(OptionInfo && "Attribute must have valid option info."); - +  bool PragmaUnroll = PragmaNameLoc->Ident->getName() == "unroll"; +  bool PragmaNoUnroll = PragmaNameLoc->Ident->getName() == "nounroll";    if (St->getStmtClass() != Stmt::DoStmtClass &&        St->getStmtClass() != Stmt::ForStmtClass &&        St->getStmtClass() != Stmt::CXXForRangeStmtClass &&        St->getStmtClass() != Stmt::WhileStmtClass) { -    const char *Pragma = PragmaNameLoc->Ident->getName() == "unroll" -                             ? "#pragma unroll" -                             : "#pragma clang loop"; +    const char *Pragma = +        llvm::StringSwitch<const char *>(PragmaNameLoc->Ident->getName()) +            .Case("unroll", "#pragma unroll") +            .Case("nounroll", "#pragma nounroll") +            .Default("#pragma clang loop");      S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma;      return nullptr;    }    LoopHintAttr::OptionType Option;    LoopHintAttr::Spelling Spelling; -  if (PragmaNameLoc->Ident->getName() == "unroll") { -    Option = ValueLoc ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll; +  if (PragmaUnroll) { +    Option = ValueExpr ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll;      Spelling = LoopHintAttr::Pragma_unroll; +  } else if (PragmaNoUnroll) { +    Option = LoopHintAttr::Unroll; +    Spelling = LoopHintAttr::Pragma_nounroll;    } else { +    assert(OptionLoc && OptionLoc->Ident && +           "Attribute must have valid option info."); +    IdentifierInfo *OptionInfo = OptionLoc->Ident;      Option = llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())                   .Case("vectorize", LoopHintAttr::Vectorize)                   .Case("vectorize_width", LoopHintAttr::VectorizeWidth) @@ -82,53 +88,45 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,      Spelling = LoopHintAttr::Pragma_clang_loop;    } -  int ValueInt; -  if (Option == LoopHintAttr::Unroll && -      Spelling == LoopHintAttr::Pragma_unroll) { -    ValueInt = 1; -  } else if (Option == LoopHintAttr::Vectorize || -             Option == LoopHintAttr::Interleave || -             Option == LoopHintAttr::Unroll) { -    if (!ValueInfo) { -      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword); -      return nullptr; -    } -    if (ValueInfo->isStr("disable")) -      ValueInt = 0; -    else if (ValueInfo->isStr("enable")) -      ValueInt = 1; -    else { -      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword); -      return nullptr; -    } +  LoopHintAttr::LoopHintState State = LoopHintAttr::Default; +  if (PragmaNoUnroll) { +    State = LoopHintAttr::Disable;    } else if (Option == LoopHintAttr::VectorizeWidth ||               Option == LoopHintAttr::InterleaveCount ||               Option == LoopHintAttr::UnrollCount) { -    // FIXME: We should support template parameters for the loop hint value. -    // See bug report #19610. -    llvm::APSInt ValueAPS; -    if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context) || -        (ValueInt = ValueAPS.getSExtValue()) < 1) { -      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value); +    assert(ValueExpr && "Attribute must have a valid value expression."); +    if (S.CheckLoopHintExpr(ValueExpr, St->getLocStart()))        return nullptr; +  } else if (Option == LoopHintAttr::Vectorize || +             Option == LoopHintAttr::Interleave || +             Option == LoopHintAttr::Unroll) { +    // Default state is assumed if StateLoc is not specified, such as with +    // '#pragma unroll'. +    if (StateLoc && StateLoc->Ident) { +      if (StateLoc->Ident->isStr("disable")) +        State = LoopHintAttr::Disable; +      else +        State = LoopHintAttr::Enable;      } -  } else -    llvm_unreachable("Unknown loop hint option"); +  } -  return LoopHintAttr::CreateImplicit(S.Context, Spelling, Option, ValueInt, -                                      A.getRange()); +  return LoopHintAttr::CreateImplicit(S.Context, Spelling, Option, State, +                                      ValueExpr, A.getRange());  } -static void CheckForIncompatibleAttributes( -    Sema &S, const SmallVectorImpl<const Attr *> &Attrs) { -  // There are 3 categories of loop hints: vectorize, interleave, and -  // unroll. Each comes in two variants: an enable/disable form and a -  // form which takes a numeric argument. For example: -  // unroll(enable|disable) and unroll_count(N). The following array -  // accumulate the hints encountered while iterating through the -  // attributes to check for compatibility. +static void +CheckForIncompatibleAttributes(Sema &S, +                               const SmallVectorImpl<const Attr *> &Attrs) { +  // There are 3 categories of loop hints attributes: vectorize, interleave, +  // and unroll. Each comes in two variants: a state form and a numeric form. +  // The state form selectively defaults/enables/disables the transformation +  // for the loop (for unroll, default indicates full unrolling rather than +  // enabling the transformation).  The numeric form form provides an integer +  // hint (for example, unroll count) to the transformer. The following array +  // accumulates the hints encountered while iterating through the attributes +  // to check for compatibility.    struct { -    const LoopHintAttr *EnableAttr; +    const LoopHintAttr *StateAttr;      const LoopHintAttr *NumericAttr;    } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}}; @@ -141,49 +139,53 @@ static void CheckForIncompatibleAttributes(      int Option = LH->getOption();      int Category; +    enum { Vectorize, Interleave, Unroll };      switch (Option) {      case LoopHintAttr::Vectorize:      case LoopHintAttr::VectorizeWidth: -      Category = 0; +      Category = Vectorize;        break;      case LoopHintAttr::Interleave:      case LoopHintAttr::InterleaveCount: -      Category = 1; +      Category = Interleave;        break;      case LoopHintAttr::Unroll:      case LoopHintAttr::UnrollCount: -      Category = 2; +      Category = Unroll;        break;      };      auto &CategoryState = HintAttrs[Category]; -    SourceLocation OptionLoc = LH->getRange().getBegin();      const LoopHintAttr *PrevAttr;      if (Option == LoopHintAttr::Vectorize ||          Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {        // Enable|disable hint.  For example, vectorize(enable). -      PrevAttr = CategoryState.EnableAttr; -      CategoryState.EnableAttr = LH; +      PrevAttr = CategoryState.StateAttr; +      CategoryState.StateAttr = LH;      } else {        // Numeric hint.  For example, vectorize_width(8).        PrevAttr = CategoryState.NumericAttr;        CategoryState.NumericAttr = LH;      } +    PrintingPolicy Policy(S.Context.getLangOpts()); +    SourceLocation OptionLoc = LH->getRange().getBegin();      if (PrevAttr)        // Cannot specify same type of attribute twice.        S.Diag(OptionLoc, diag::err_pragma_loop_compatibility) -          << /*Duplicate=*/true << PrevAttr->getDiagnosticName() -          << LH->getDiagnosticName(); - -    if (CategoryState.EnableAttr && !CategoryState.EnableAttr->getValue() && -        CategoryState.NumericAttr) { -      // Disable hints are not compatible with numeric hints of the -      // same category. +          << /*Duplicate=*/true << PrevAttr->getDiagnosticName(Policy) +          << LH->getDiagnosticName(Policy); + +    if (CategoryState.StateAttr && CategoryState.NumericAttr && +        (Category == Unroll || +         CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) { +      // Disable hints are not compatible with numeric hints of the same +      // category.  As a special case, numeric unroll hints are also not +      // compatible with "enable" form of the unroll pragma, unroll(full).        S.Diag(OptionLoc, diag::err_pragma_loop_compatibility)            << /*Duplicate=*/false -          << CategoryState.EnableAttr->getDiagnosticName() -          << CategoryState.NumericAttr->getDiagnosticName(); +          << CategoryState.StateAttr->getDiagnosticName(Policy) +          << CategoryState.NumericAttr->getDiagnosticName(Policy);      }    }  } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 7e8f0b721dfe..67c36a5fb5e9 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -107,7 +107,7 @@ void Sema::FilterAcceptableTemplateNames(LookupResult &R,        //   template itself and not a specialization thereof, and is not        //   ambiguous.        if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl)) -        if (!ClassTemplates.insert(ClassTmpl)) { +        if (!ClassTemplates.insert(ClassTmpl).second) {            filter.erase();            continue;          } @@ -318,15 +318,14 @@ void Sema::LookupTemplateName(LookupResult &Found,      DeclarationName Name = Found.getLookupName();      Found.clear();      // Simple filter callback that, for keywords, only accepts the C++ *_cast -    CorrectionCandidateCallback FilterCCC; -    FilterCCC.WantTypeSpecifiers = false; -    FilterCCC.WantExpressionKeywords = false; -    FilterCCC.WantRemainingKeywords = false; -    FilterCCC.WantCXXNamedCasts = true; -    if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(), -                                               Found.getLookupKind(), S, &SS, -                                               FilterCCC, CTK_ErrorRecovery, -                                               LookupCtx)) { +    auto FilterCCC = llvm::make_unique<CorrectionCandidateCallback>(); +    FilterCCC->WantTypeSpecifiers = false; +    FilterCCC->WantExpressionKeywords = false; +    FilterCCC->WantRemainingKeywords = false; +    FilterCCC->WantCXXNamedCasts = true; +    if (TypoCorrection Corrected = CorrectTypo( +            Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, +            std::move(FilterCCC), CTK_ErrorRecovery, LookupCtx)) {        Found.setLookupName(Corrected.getCorrection());        if (Corrected.getCorrectionDecl())          Found.addDecl(Corrected.getCorrectionDecl()); @@ -652,12 +651,8 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {    //   A non-type template-parameter of type "array of T" or    //   "function returning T" is adjusted to be of type "pointer to    //   T" or "pointer to function returning T", respectively. -  else if (T->isArrayType()) -    // FIXME: Keep the type prior to promotion? -    return Context.getArrayDecayedType(T); -  else if (T->isFunctionType()) -    // FIXME: Keep the type prior to promotion? -    return Context.getPointerType(T); +  else if (T->isArrayType() || T->isFunctionType()) +    return Context.getDecayedType(T);    Diag(Loc, diag::err_template_nontype_parm_bad_type)      << T; @@ -720,7 +715,8 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,        return Param;      TemplateArgument Converted; -    ExprResult DefaultRes = CheckTemplateArgument(Param, Param->getType(), Default, Converted); +    ExprResult DefaultRes = +        CheckTemplateArgument(Param, Param->getType(), Default, Converted);      if (DefaultRes.isInvalid()) {        Param->setInvalidDecl();        return Param; @@ -1105,9 +1101,13 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,    AddPushedVisibilityAttribute(NewClass); -  if (TUK != TUK_Friend) -    PushOnScopeChains(NewTemplate, S); -  else { +  if (TUK != TUK_Friend) { +    // Per C++ [basic.scope.temp]p2, skip the template parameter scopes. +    Scope *Outer = S; +    while ((Outer->getFlags() & Scope::TemplateParamScope) != 0) +      Outer = Outer->getParent(); +    PushOnScopeChains(NewTemplate, Outer); +  } else {      if (PrevClassTemplate && PrevClassTemplate->getAccess() != AS_none) {        NewTemplate->setAccess(PrevClassTemplate->getAccess());        NewClass->setAccess(PrevClassTemplate->getAccess()); @@ -2396,7 +2396,7 @@ makeTemplateArgumentListInfo(Sema &S, TemplateIdAnnotation &TemplateId) {  DeclResult Sema::ActOnVarTemplateSpecialization(      Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc, -    TemplateParameterList *TemplateParams, VarDecl::StorageClass SC, +    TemplateParameterList *TemplateParams, StorageClass SC,      bool IsPartialSpecialization) {    // D must be variable template id.    assert(D.getName().getKind() == UnqualifiedId::IK_TemplateId && @@ -4106,6 +4106,7 @@ bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(    case NestedNameSpecifier::Namespace:    case NestedNameSpecifier::NamespaceAlias:    case NestedNameSpecifier::Global: +  case NestedNameSpecifier::Super:      return false;    case NestedNameSpecifier::TypeSpec: @@ -4595,8 +4596,8 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,      return true;    // Create the template argument. -  Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()), -                               ParamType->isReferenceType()); +  Converted = +      TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()), ParamType);    S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity, false);    return false;  } @@ -4691,7 +4692,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,              Converted = TemplateArgument(Arg);            } else {              VD = cast<ValueDecl>(VD->getCanonicalDecl()); -            Converted = TemplateArgument(VD, /*isReferenceParam*/false); +            Converted = TemplateArgument(VD, ParamType);            }            return Invalid;          } @@ -4720,7 +4721,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,        Converted = TemplateArgument(Arg);      } else {        ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl()); -      Converted = TemplateArgument(D, /*isReferenceParam*/false); +      Converted = TemplateArgument(D, ParamType);      }      return Invalid;    } @@ -4738,30 +4739,152 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,  ///  /// This routine implements the semantics of C++ [temp.arg.nontype].  /// If an error occurred, it returns ExprError(); otherwise, it -/// returns the converted template argument. \p -/// InstantiatedParamType is the type of the non-type template -/// parameter after it has been instantiated. +/// returns the converted template argument. \p ParamType is the +/// type of the non-type template parameter after it has been instantiated.  ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, -                                       QualType InstantiatedParamType, Expr *Arg, +                                       QualType ParamType, Expr *Arg,                                         TemplateArgument &Converted,                                         CheckTemplateArgumentKind CTAK) {    SourceLocation StartLoc = Arg->getLocStart();    // If either the parameter has a dependent type or the argument is    // type-dependent, there's nothing we can check now. -  if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) { +  if (ParamType->isDependentType() || Arg->isTypeDependent()) {      // FIXME: Produce a cloned, canonical expression?      Converted = TemplateArgument(Arg);      return Arg;    } +  // We should have already dropped all cv-qualifiers by now. +  assert(!ParamType.hasQualifiers() && +         "non-type template parameter type cannot be qualified"); + +  if (CTAK == CTAK_Deduced && +      !Context.hasSameUnqualifiedType(ParamType, Arg->getType())) { +    // C++ [temp.deduct.type]p17: +    //   If, in the declaration of a function template with a non-type +    //   template-parameter, the non-type template-parameter is used +    //   in an expression in the function parameter-list and, if the +    //   corresponding template-argument is deduced, the +    //   template-argument type shall match the type of the +    //   template-parameter exactly, except that a template-argument +    //   deduced from an array bound may be of any integral type. +    Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) +      << Arg->getType().getUnqualifiedType() +      << ParamType.getUnqualifiedType(); +    Diag(Param->getLocation(), diag::note_template_param_here); +    return ExprError(); +  } + +  if (getLangOpts().CPlusPlus1z) { +    // FIXME: We can do some limited checking for a value-dependent but not +    // type-dependent argument. +    if (Arg->isValueDependent()) { +      Converted = TemplateArgument(Arg); +      return Arg; +    } + +    // C++1z [temp.arg.nontype]p1: +    //   A template-argument for a non-type template parameter shall be +    //   a converted constant expression of the type of the template-parameter. +    APValue Value; +    ExprResult ArgResult = CheckConvertedConstantExpression( +        Arg, ParamType, Value, CCEK_TemplateArg); +    if (ArgResult.isInvalid()) +      return ExprError(); + +    QualType CanonParamType = Context.getCanonicalType(ParamType); + +    // Convert the APValue to a TemplateArgument. +    switch (Value.getKind()) { +    case APValue::Uninitialized: +      assert(ParamType->isNullPtrType()); +      Converted = TemplateArgument(CanonParamType, /*isNullPtr*/true); +      break; +    case APValue::Int: +      assert(ParamType->isIntegralOrEnumerationType()); +      Converted = TemplateArgument(Context, Value.getInt(), CanonParamType); +      break; +    case APValue::MemberPointer: { +      assert(ParamType->isMemberPointerType()); + +      // FIXME: We need TemplateArgument representation and mangling for these. +      if (!Value.getMemberPointerPath().empty()) { +        Diag(Arg->getLocStart(), +             diag::err_template_arg_member_ptr_base_derived_not_supported) +            << Value.getMemberPointerDecl() << ParamType +            << Arg->getSourceRange(); +        return ExprError(); +      } + +      auto *VD = const_cast<ValueDecl*>(Value.getMemberPointerDecl()); +      Converted = VD ? TemplateArgument(VD, CanonParamType) +                     : TemplateArgument(CanonParamType, /*isNullPtr*/true); +      break; +    } +    case APValue::LValue: { +      //   For a non-type template-parameter of pointer or reference type, +      //   the value of the constant expression shall not refer to +      assert(ParamType->isPointerType() || ParamType->isReferenceType() || +             ParamType->isNullPtrType()); +      // -- a temporary object +      // -- a string literal +      // -- the result of a typeid expression, or +      // -- a predefind __func__ variable +      if (auto *E = Value.getLValueBase().dyn_cast<const Expr*>()) { +        if (isa<CXXUuidofExpr>(E)) { +          Converted = TemplateArgument(const_cast<Expr*>(E)); +          break; +        } +        Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) +          << Arg->getSourceRange(); +        return ExprError(); +      } +      auto *VD = const_cast<ValueDecl *>( +          Value.getLValueBase().dyn_cast<const ValueDecl *>()); +      // -- a subobject +      if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 && +          VD && VD->getType()->isArrayType() && +          Value.getLValuePath()[0].ArrayIndex == 0 && +          !Value.isLValueOnePastTheEnd() && ParamType->isPointerType()) { +        // Per defect report (no number yet): +        //   ... other than a pointer to the first element of a complete array +        //       object. +      } else if (!Value.hasLValuePath() || Value.getLValuePath().size() || +                 Value.isLValueOnePastTheEnd()) { +        Diag(StartLoc, diag::err_non_type_template_arg_subobject) +          << Value.getAsString(Context, ParamType); +        return ExprError(); +      } +      assert((VD || !ParamType->isReferenceType()) && +             "null reference should not be a constant expression"); +      assert((!VD || !ParamType->isNullPtrType()) && +             "non-null value of type nullptr_t?"); +      Converted = VD ? TemplateArgument(VD, CanonParamType) +                     : TemplateArgument(CanonParamType, /*isNullPtr*/true); +      break; +    } +    case APValue::AddrLabelDiff: +      return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_diff); +    case APValue::Float: +    case APValue::ComplexInt: +    case APValue::ComplexFloat: +    case APValue::Vector: +    case APValue::Array: +    case APValue::Struct: +    case APValue::Union: +      llvm_unreachable("invalid kind for template argument"); +    } + +    return ArgResult.get(); +  } +    // C++ [temp.arg.nontype]p5:    //   The following conversions are performed on each expression used    //   as a non-type template-argument. If a non-type    //   template-argument cannot be converted to the type of the    //   corresponding template-parameter then the program is    //   ill-formed. -  QualType ParamType = InstantiatedParamType;    if (ParamType->isIntegralOrEnumerationType()) {      // C++11:      //   -- for a non-type template-parameter of integral or @@ -4773,23 +4896,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,      //      enumeration type, integral promotions (4.5) and integral      //      conversions (4.7) are applied. -    if (CTAK == CTAK_Deduced && -        !Context.hasSameUnqualifiedType(ParamType, Arg->getType())) { -      // C++ [temp.deduct.type]p17: -      //   If, in the declaration of a function template with a non-type -      //   template-parameter, the non-type template-parameter is used -      //   in an expression in the function parameter-list and, if the -      //   corresponding template-argument is deduced, the -      //   template-argument type shall match the type of the -      //   template-parameter exactly, except that a template-argument -      //   deduced from an array bound may be of any integral type. -      Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) -        << Arg->getType().getUnqualifiedType() -        << ParamType.getUnqualifiedType(); -      Diag(Param->getLocation(), diag::note_template_param_here); -      return ExprError(); -    } -      if (getLangOpts().CPlusPlus11) {        // We can't check arbitrary value-dependent arguments.        // FIXME: If there's no viable conversion to the template parameter type, @@ -4867,9 +4973,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,          return ExprError();      } -    // From here on out, all we care about are the unqualified forms -    // of the parameter and argument types. -    ParamType = ParamType.getUnqualifiedType(); +    // From here on out, all we care about is the unqualified form +    // of the argument type.      ArgType = ArgType.getUnqualifiedType();      // Try to convert the argument to the parameter's type. @@ -4886,7 +4991,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,        // We can't perform this conversion.        Diag(Arg->getLocStart(),             diag::err_template_arg_not_convertible) -        << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); +        << Arg->getType() << ParamType << Arg->getSourceRange();        Diag(Param->getLocation(), diag::note_template_param_here);        return ExprError();      } @@ -6329,14 +6434,11 @@ Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,  /// \brief Strips various properties off an implicit instantiation  /// that has just been explicitly specialized.  static void StripImplicitInstantiation(NamedDecl *D) { -  D->dropAttrs(); +  D->dropAttr<DLLImportAttr>(); +  D->dropAttr<DLLExportAttr>(); -  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { +  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))      FD->setInlineSpecified(false); - -    for (auto I : FD->params()) -      I->dropAttrs(); -  }  }  /// \brief Compute the diagnostic location for an explicit instantiation @@ -7606,6 +7708,29 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,    // Ignore access control bits, we don't need them for redeclaration checking.    FunctionDecl *Specialization = cast<FunctionDecl>(*Result); +  // C++11 [except.spec]p4 +  // In an explicit instantiation an exception-specification may be specified, +  // but is not required. +  // If an exception-specification is specified in an explicit instantiation +  // directive, it shall be compatible with the exception-specifications of +  // other declarations of that function. +  if (auto *FPT = R->getAs<FunctionProtoType>()) +    if (FPT->hasExceptionSpec()) { +      unsigned DiagID = +          diag::err_mismatched_exception_spec_explicit_instantiation; +      if (getLangOpts().MicrosoftExt) +        DiagID = diag::ext_mismatched_exception_spec_explicit_instantiation; +      bool Result = CheckEquivalentExceptionSpec( +          PDiag(DiagID) << Specialization->getType(), +          PDiag(diag::note_explicit_instantiation_here), +          Specialization->getType()->getAs<FunctionProtoType>(), +          Specialization->getLocation(), FPT, D.getLocStart()); +      // In Microsoft mode, mismatching exception specifications just cause a +      // warning. +      if (!getLangOpts().MicrosoftExt && Result) +        return true; +    } +    if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) {      Diag(D.getIdentifierLoc(),           diag::err_explicit_instantiation_member_function_not_instantiated) @@ -7879,7 +8004,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,    DeclarationName Name(&II);    LookupResult Result(*this, Name, IILoc, LookupOrdinaryName); -  LookupQualifiedName(Result, Ctx); +  LookupQualifiedName(Result, Ctx, SS);    unsigned DiagID = 0;    Decl *Referenced = nullptr;    switch (Result.getResultKind()) { @@ -7924,6 +8049,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,      if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {        // We found a type. Build an ElaboratedType, since the        // typename-specifier was just sugar. +      MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);        return Context.getElaboratedType(ETK_Typename,                                          QualifierLoc.getNestedNameSpecifier(),                                         Context.getTypeDeclType(Type)); diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 53a75d227c7b..dd2a4d26979e 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -262,8 +262,7 @@ checkDeducedTemplateArguments(ASTContext &Context,      // If we deduced two declarations, make sure they they refer to the      // same declaration.      if (Y.getKind() == TemplateArgument::Declaration && -        isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) && -        X.isDeclForReferenceParam() == Y.isDeclForReferenceParam()) +        isSameDeclaration(X.getAsDecl(), Y.getAsDecl()))        return X;      // All other combinations are incompatible. @@ -384,7 +383,7 @@ DeduceNonTypeTemplateArgument(Sema &S,           "Cannot deduce non-type template argument with depth > 0");    D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr; -  TemplateArgument New(D, NTTP->getType()->isReferenceType()); +  TemplateArgument New(D, NTTP->getType());    DeducedTemplateArgument NewDeduced(New);    DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,                                                       Deduced[NTTP->getIndex()], @@ -1302,7 +1301,8 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,      //     T &      case Type::LValueReference: { -      const LValueReferenceType *ReferenceArg = Arg->getAs<LValueReferenceType>(); +      const LValueReferenceType *ReferenceArg = +          Arg->getAs<LValueReferenceType>();        if (!ReferenceArg)          return Sema::TDK_NonDeducedMismatch; @@ -1313,7 +1313,8 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,      //     T && [C++0x]      case Type::RValueReference: { -      const RValueReferenceType *ReferenceArg = Arg->getAs<RValueReferenceType>(); +      const RValueReferenceType *ReferenceArg = +          Arg->getAs<RValueReferenceType>();        if (!ReferenceArg)          return Sema::TDK_NonDeducedMismatch; @@ -1492,7 +1493,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,              const RecordType *NextT = ToVisit.pop_back_val();              // If we have already seen this type, skip it. -            if (!Visited.insert(NextT)) +            if (!Visited.insert(NextT).second)                continue;              // If this is a base class, try to perform template argument @@ -1726,8 +1727,7 @@ DeduceTemplateArguments(Sema &S,    case TemplateArgument::Declaration:      if (Arg.getKind() == TemplateArgument::Declaration && -        isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()) && -        Param.isDeclForReferenceParam() == Arg.isDeclForReferenceParam()) +        isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()))        return Sema::TDK_Success;      Info.FirstArg = Param; @@ -1962,8 +1962,7 @@ static bool isSameTemplateArg(ASTContext &Context,               Context.getCanonicalType(Y.getAsType());      case TemplateArgument::Declaration: -      return isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) && -             X.isDeclForReferenceParam() == Y.isDeclForReferenceParam(); +      return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());      case TemplateArgument::NullPtr:        return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType()); @@ -2056,7 +2055,8 @@ getTrivialTemplateArgumentLoc(Sema &S,        TemplateName Template = Arg.getAsTemplate();        if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())          Builder.MakeTrivial(S.Context, DTN->getQualifier(), Loc); -      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) +      else if (QualifiedTemplateName *QTN = +                   Template.getAsQualifiedTemplateName())          Builder.MakeTrivial(S.Context, QTN->getQualifier(), Loc);        if (Arg.getKind() == TemplateArgument::Template) @@ -2588,6 +2588,9 @@ Sema::SubstituteExplicitTemplateArguments(      = Function->getType()->getAs<FunctionProtoType>();    assert(Proto && "Function template does not have a prototype?"); +  // Isolate our substituted parameters from our caller. +  LocalInstantiationScope InstScope(*this, /*MergeWithOuterScope*/true); +    // Instantiate the types of each of the function parameters given the    // explicitly-specified template arguments. If the function has a trailing    // return type, substitute it after the arguments to ensure we substitute @@ -3000,7 +3003,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,  static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,                                    FunctionDecl *Fn) {    // We may need to deduce the return type of the function now. -  if (S.getLangOpts().CPlusPlus1y && Fn->getReturnType()->isUndeducedType() && +  if (S.getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&        S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/ false))      return QualType(); @@ -3229,9 +3232,9 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,    return false;  } -static bool hasDeducibleTemplateParameters(Sema &S, -                                           FunctionTemplateDecl *FunctionTemplate, -                                           QualType T); +static bool +hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, +                               QualType T);  /// \brief Perform template argument deduction by matching a parameter type  ///        against a single expression, where the expression is an element of @@ -3488,8 +3491,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(    }    return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, -                                         NumExplicitlySpecified, -                                         Specialization, Info, &OriginalCallArgs); +                                         NumExplicitlySpecified, Specialization, +                                         Info, &OriginalCallArgs);  }  QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, @@ -3579,7 +3582,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,    // If the function has a deduced return type, substitute it for a dependent    // type so that we treat it as a non-deduced context in what follows.    bool HasDeducedReturnType = false; -  if (getLangOpts().CPlusPlus1y && InOverloadResolution && +  if (getLangOpts().CPlusPlus14 && InOverloadResolution &&        Function->getReturnType()->getContainedAutoType()) {      FunctionType = SubstAutoType(FunctionType, Context.DependentTy);      HasDeducedReturnType = true; @@ -3788,7 +3791,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate,      // C++0x [temp.deduct.conv]p4:      //   If A is a cv-qualified type, the top level cv-qualifiers of A's -    //   type are ignored for type deduction. If A is a reference type, the type  +    //   type are ignored for type deduction. If A is a reference type, the type      //   referred to by A is used for type deduction.      A = A.getUnqualifiedType();    } @@ -3842,8 +3845,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate,    Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);    // If the conversion operator is being invoked on a lambda closure to convert -  // to a ptr-to-function, use the deduced arguments from the conversion function -  // to specialize the corresponding call operator. +  // to a ptr-to-function, use the deduced arguments from the conversion +  // function to specialize the corresponding call operator.    //   e.g., int (*fp)(int) = [](auto a) { return a; };    if (Result == TDK_Success && isLambdaConversionOperator(ConversionGeneric)) { @@ -3907,9 +3910,10 @@ namespace {      public TreeTransform<SubstituteAutoTransform> {      QualType Replacement;    public: -    SubstituteAutoTransform(Sema &SemaRef, QualType Replacement) : -      TreeTransform<SubstituteAutoTransform>(SemaRef), Replacement(Replacement) { -    } +    SubstituteAutoTransform(Sema &SemaRef, QualType Replacement) +        : TreeTransform<SubstituteAutoTransform>(SemaRef), +          Replacement(Replacement) {} +      QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) {        // If we're building the type pattern to deduce against, don't wrap the        // substituted type in an AutoType. Certain template deduction rules @@ -3988,7 +3992,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) {          return DAR_FailedAlreadyDiagnosed;        } -      QualType Deduced = BuildDecltypeType(Init, Init->getLocStart()); +      QualType Deduced = BuildDecltypeType(Init, Init->getLocStart(), false);        // FIXME: Support a non-canonical deduced type for 'auto'.        Deduced = Context.getCanonicalType(Deduced);        Result = SubstituteAutoTransform(*this, Deduced).Apply(Type); @@ -4885,8 +4889,8 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,                                 Depth, Used);      // C++0x [temp.deduct.type]p9: -    //   If the template argument list of P contains a pack expansion that is not -    //   the last template argument, the entire template argument list is a +    //   If the template argument list of P contains a pack expansion that is +    //   not the last template argument, the entire template argument list is a      //   non-deduced context.      if (OnlyDeduced &&          hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs())) @@ -5069,10 +5073,9 @@ Sema::MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,  /// \brief Marks all of the template parameters that will be deduced by a  /// call to the given function template. -void -Sema::MarkDeducedTemplateParameters(ASTContext &Ctx, -                                    const FunctionTemplateDecl *FunctionTemplate, -                                    llvm::SmallBitVector &Deduced) { +void Sema::MarkDeducedTemplateParameters( +    ASTContext &Ctx, const FunctionTemplateDecl *FunctionTemplate, +    llvm::SmallBitVector &Deduced) {    TemplateParameterList *TemplateParams      = FunctionTemplate->getTemplateParameters();    Deduced.clear(); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 14c64050168a..6ac7175cf30f 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -448,6 +448,10 @@ void Sema::PrintInstantiationStack() {                       diag::note_template_enum_def_here)            << ED            << Active->InstantiationRange; +      } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { +        Diags.Report(Active->PointOfInstantiation, +                     diag::note_template_nsdmi_here) +            << FD << Active->InstantiationRange;        } else {          Diags.Report(Active->PointOfInstantiation,                       diag::note_template_type_alias_instantiation_here) @@ -767,6 +771,8 @@ namespace {                            QualType ObjectType = QualType(),                            NamedDecl *FirstQualifierInScope = nullptr); +    const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH); +      ExprResult TransformPredefinedExpr(PredefinedExpr *E);      ExprResult TransformDeclRefExpr(DeclRefExpr *E);      ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E); @@ -789,11 +795,17 @@ namespace {      ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);      QualType TransformFunctionProtoType(TypeLocBuilder &TLB, -                                        FunctionProtoTypeLoc TL); +                                        FunctionProtoTypeLoc TL) { +      // Call the base version; it will forward to our overridden version below. +      return inherited::TransformFunctionProtoType(TLB, TL); +    } + +    template<typename Fn>      QualType TransformFunctionProtoType(TypeLocBuilder &TLB,                                          FunctionProtoTypeLoc TL,                                          CXXRecordDecl *ThisContext, -                                        unsigned ThisTypeQuals); +                                        unsigned ThisTypeQuals, +                                        Fn TransformExceptionSpec);      ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,                                              int indexAdjustment, @@ -1023,7 +1035,7 @@ TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,  TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS,                                                           TemplateName Name, -                                                         SourceLocation NameLoc,                                      +                                                         SourceLocation NameLoc,                                                           QualType ObjectType,                                               NamedDecl *FirstQualifierInScope) {    if (TemplateTemplateParmDecl *TTP @@ -1127,6 +1139,24 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,    return transformNonTypeTemplateParmRef(NTTP, E->getLocation(), Arg);  } +const LoopHintAttr * +TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) { +  Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get(); + +  if (TransformedExpr == LH->getValue()) +    return LH; + +  // Generate error if there is a problem with the value. +  if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation())) +    return LH; + +  // Create new LoopHintValueAttr with integral expression in place of the +  // non-type template parameter. +  return LoopHintAttr::CreateImplicit( +      getSema().Context, LH->getSemanticSpelling(), LH->getOption(), +      LH->getState(), TransformedExpr, LH->getRange()); +} +  ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(                                                   NonTypeTemplateParmDecl *parm,                                                   SourceLocation loc, @@ -1255,8 +1285,8 @@ TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,    Decl *TransformedDecl;    if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) { -    // If this is a reference to a function parameter pack which we can substitute -    // but can't yet expand, build a FunctionParmPackExpr for it. +    // If this is a reference to a function parameter pack which we can +    // substitute but can't yet expand, build a FunctionParmPackExpr for it.      if (getSema().ArgumentPackSubstitutionIndex == -1) {        QualType T = TransformType(E->getType());        if (T.isNull()) @@ -1307,21 +1337,16 @@ ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(                                          E->getParam());  } -QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, -                                                      FunctionProtoTypeLoc TL) { -  // We need a local instantiation scope for this function prototype. -  LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); -  return inherited::TransformFunctionProtoType(TLB, TL); -} - +template<typename Fn>  QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,                                   FunctionProtoTypeLoc TL,                                   CXXRecordDecl *ThisContext, -                                 unsigned ThisTypeQuals) { +                                 unsigned ThisTypeQuals, +                                 Fn TransformExceptionSpec) {    // We need a local instantiation scope for this function prototype.    LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); -  return inherited::TransformFunctionProtoType(TLB, TL, ThisContext,  -                                               ThisTypeQuals);   +  return inherited::TransformFunctionProtoType( +      TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);  }  ParmVarDecl * @@ -1556,7 +1581,8 @@ static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {  /// A form of SubstType intended specifically for instantiating the  /// type of a FunctionDecl.  Its purpose is solely to force the -/// instantiation of default-argument expressions. +/// instantiation of default-argument expressions and to avoid +/// instantiating an exception-specification.  TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,                                  const MultiLevelTemplateArgumentList &Args,                                  SourceLocation Loc, @@ -1579,9 +1605,17 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,    QualType Result; -  if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) { -    Result = Instantiator.TransformFunctionProtoType(TLB, Proto, ThisContext, -                                                     ThisTypeQuals); +  if (FunctionProtoTypeLoc Proto = +          TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) { +    // Instantiate the type, other than its exception specification. The +    // exception specification is instantiated in InitFunctionInstantiation +    // once we've built the FunctionDecl. +    // FIXME: Set the exception specification to EST_Uninstantiated here, +    // instead of rebuilding the function type again later. +    Result = Instantiator.TransformFunctionProtoType( +        TLB, Proto, ThisContext, ThisTypeQuals, +        [](FunctionProtoType::ExceptionSpecInfo &ESI, +           bool &Changed) { return false; });    } else {      Result = Instantiator.TransformType(TLB, TL);    } @@ -1591,6 +1625,26 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,    return TLB.getTypeSourceInfo(Context, Result);  } +void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, +                              const MultiLevelTemplateArgumentList &Args) { +  FunctionProtoType::ExceptionSpecInfo ESI = +      Proto->getExtProtoInfo().ExceptionSpec; +  assert(ESI.Type != EST_Uninstantiated); + +  TemplateInstantiator Instantiator(*this, Args, New->getLocation(), +                                    New->getDeclName()); + +  SmallVector<QualType, 4> ExceptionStorage; +  bool Changed = false; +  if (Instantiator.TransformExceptionSpec( +          New->getTypeSourceInfo()->getTypeLoc().getLocEnd(), ESI, +          ExceptionStorage, Changed)) +    // On error, recover by dropping the exception specification. +    ESI.Type = EST_None; + +  UpdateExceptionSpec(New, ESI); +} +  ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,                               const MultiLevelTemplateArgumentList &TemplateArgs,                                      int indexAdjustment, @@ -1947,8 +2001,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,    TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);    SmallVector<Decl*, 4> Fields; -  SmallVector<std::pair<FieldDecl*, FieldDecl*>, 4> -    FieldsWithMemberInitializers;    // Delay instantiation of late parsed attributes.    LateInstantiatedAttrVec LateAttrs;    Instantiator.enableLateAttributeInstantiation(&LateAttrs); @@ -1975,10 +2027,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,      if (NewMember) {        if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {          Fields.push_back(Field); -        FieldDecl *OldField = cast<FieldDecl>(Member); -        if (OldField->getInClassInitializer()) -          FieldsWithMemberInitializers.push_back(std::make_pair(OldField, -                                                                Field));        } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(NewMember)) {          // C++11 [temp.inst]p1: The implicit instantiation of a class template          // specialization causes the implicit instantiation of the definitions @@ -2015,31 +2063,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,                SourceLocation(), SourceLocation(), nullptr);    CheckCompletedCXXClass(Instantiation); -  // Attach any in-class member initializers now the class is complete. -  // FIXME: We are supposed to defer instantiating these until they are needed. -  if (!FieldsWithMemberInitializers.empty()) { -    // C++11 [expr.prim.general]p4: -    //   Otherwise, if a member-declarator declares a non-static data member  -    //  (9.2) of a class X, the expression this is a prvalue of type "pointer -    //  to X" within the optional brace-or-equal-initializer. It shall not  -    //  appear elsewhere in the member-declarator. -    CXXThisScopeRAII ThisScope(*this, Instantiation, (unsigned)0); -     -    for (unsigned I = 0, N = FieldsWithMemberInitializers.size(); I != N; ++I) { -      FieldDecl *OldField = FieldsWithMemberInitializers[I].first; -      FieldDecl *NewField = FieldsWithMemberInitializers[I].second; -      Expr *OldInit = OldField->getInClassInitializer(); - -      ActOnStartCXXInClassMemberInitializer(); -      ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs, -                                            /*CXXDirectInit=*/false); -      Expr *Init = NewInit.get(); -      assert((!Init || !isa<ParenListExpr>(Init)) && -             "call-style init in class"); -      ActOnFinishCXXInClassMemberInitializer(NewField, -        Init ? Init->getLocStart() : SourceLocation(), Init); -    } -  }    // Instantiate late parsed attributes, and attach them to their decls.    // See Sema::InstantiateAttrs    for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(), @@ -2180,6 +2203,80 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,    return Instantiation->isInvalidDecl();  } + +/// \brief Instantiate the definition of a field from the given pattern. +/// +/// \param PointOfInstantiation The point of instantiation within the +///        source code. +/// \param Instantiation is the declaration whose definition is being +///        instantiated. This will be a class of a class temploid +///        specialization, or a local enumeration within a function temploid +///        specialization. +/// \param Pattern The templated declaration from which the instantiation +///        occurs. +/// \param TemplateArgs The template arguments to be substituted into +///        the pattern. +/// +/// \return \c true if an error occurred, \c false otherwise. +bool Sema::InstantiateInClassInitializer( +    SourceLocation PointOfInstantiation, FieldDecl *Instantiation, +    FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) { +  // If there is no initializer, we don't need to do anything. +  if (!Pattern->hasInClassInitializer()) +    return false; + +  assert(Instantiation->getInClassInitStyle() == +             Pattern->getInClassInitStyle() && +         "pattern and instantiation disagree about init style"); + +  // Error out if we haven't parsed the initializer of the pattern yet because +  // we are waiting for the closing brace of the outer class. +  Expr *OldInit = Pattern->getInClassInitializer(); +  if (!OldInit) { +    RecordDecl *PatternRD = Pattern->getParent(); +    RecordDecl *OutermostClass = PatternRD->getOuterLexicalRecordContext(); +    if (OutermostClass == PatternRD) { +      Diag(Pattern->getLocEnd(), diag::err_in_class_initializer_not_yet_parsed) +          << PatternRD << Pattern; +    } else { +      Diag(Pattern->getLocEnd(), +           diag::err_in_class_initializer_not_yet_parsed_outer_class) +          << PatternRD << OutermostClass << Pattern; +    } +    Instantiation->setInvalidDecl(); +    return true; +  } + +  InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation); +  if (Inst.isInvalid()) +    return true; + +  // Enter the scope of this instantiation. We don't use PushDeclContext because +  // we don't have a scope. +  ContextRAII SavedContext(*this, Instantiation->getParent()); +  EnterExpressionEvaluationContext EvalContext(*this, +                                               Sema::PotentiallyEvaluated); + +  LocalInstantiationScope Scope(*this); + +  // Instantiate the initializer. +  ActOnStartCXXInClassMemberInitializer(); +  CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), /*TypeQuals=*/0); + +  ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs, +                                        /*CXXDirectInit=*/false); +  Expr *Init = NewInit.get(); +  assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class"); +  ActOnFinishCXXInClassMemberInitializer( +      Instantiation, Init ? Init->getLocStart() : SourceLocation(), Init); + +  // Exit the scope of this instantiation. +  SavedContext.pop(); + +  // Return true if the in-class initializer is still missing. +  return !Instantiation->getInClassInitializer(); +} +  namespace {    /// \brief A partial specialization whose template arguments have matched    /// a given template-id. @@ -2458,7 +2555,10 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,        // Always skip the injected-class-name, along with any        // redeclarations of nested classes, since both would cause us        // to try to instantiate the members of a class twice. -      if (Record->isInjectedClassName() || Record->getPreviousDecl()) +      // Skip closure types; they'll get instantiated when we instantiate +      // the corresponding lambda-expression. +      if (Record->isInjectedClassName() || Record->getPreviousDecl() || +          Record->isLambda())          continue;        MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo(); @@ -2541,6 +2641,19 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,          MSInfo->setTemplateSpecializationKind(TSK);          MSInfo->setPointOfInstantiation(PointOfInstantiation);        } +    } else if (auto *Field = dyn_cast<FieldDecl>(D)) { +      // No need to instantiate in-class initializers during explicit +      // instantiation. +      if (Field->hasInClassInitializer() && TSK == TSK_ImplicitInstantiation) { +        CXXRecordDecl *ClassPattern = +            Instantiation->getTemplateInstantiationPattern(); +        DeclContext::lookup_result Lookup = +            ClassPattern->lookup(Field->getDeclName()); +        assert(Lookup.size() == 1); +        FieldDecl *Pattern = cast<FieldDecl>(Lookup[0]); +        InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern, +                                      TemplateArgs); +      }      }    }  } @@ -2649,8 +2762,7 @@ bool Sema::Subst(const TemplateArgumentLoc *Args, unsigned NumArgs,    return Instantiator.TransformTemplateArguments(Args, NumArgs, Result);  } - -static const Decl* getCanonicalParmVarDecl(const Decl *D) { +static const Decl *getCanonicalParmVarDecl(const Decl *D) {    // When storing ParmVarDecls in the local instantiation scope, we always    // want to use the ParmVarDecl from the canonical function declaration,    // since the map is then valid for any redeclaration or definition of that @@ -2658,7 +2770,10 @@ static const Decl* getCanonicalParmVarDecl(const Decl *D) {    if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {        unsigned i = PV->getFunctionScopeIndex(); -      return FD->getCanonicalDecl()->getParamDecl(i); +      // This parameter might be from a freestanding function type within the +      // function and isn't necessarily referring to one of FD's parameters. +      if (FD->getParamDecl(i) == PV) +        return FD->getCanonicalDecl()->getParamDecl(i);      }    }    return D; @@ -2707,12 +2822,22 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) {  void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {    D = getCanonicalParmVarDecl(D);    llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D]; -  if (Stored.isNull()) +  if (Stored.isNull()) { +#ifndef NDEBUG +    // It should not be present in any surrounding scope either. +    LocalInstantiationScope *Current = this; +    while (Current->CombineWithOuterScope && Current->Outer) { +      Current = Current->Outer; +      assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() && +             "Instantiated local in inner and outer scopes"); +    } +#endif      Stored = Inst; -  else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>()) +  } else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>()) {      Pack->push_back(Inst); -  else +  } else {      assert(Stored.get<Decl *>() == Inst && "Already instantiated this local"); +  }  }  void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,  @@ -2723,9 +2848,16 @@ void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,  }  void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) { +#ifndef NDEBUG +  // This should be the first time we've been told about this decl. +  for (LocalInstantiationScope *Current = this; +       Current && Current->CombineWithOuterScope; Current = Current->Outer) +    assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() && +           "Creating local pack after instantiation of local"); +#endif +    D = getCanonicalParmVarDecl(D);    llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D]; -  assert(Stored.isNull() && "Already instantiated this local");    DeclArgumentPack *Pack = new DeclArgumentPack;    Stored = Pack;    ArgumentPacks.push_back(Pack); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index accec95bf708..40e86175b2cd 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -36,14 +36,24 @@ static bool isDeclWithinFunction(const Decl *D) {    return false;  } -bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, -                                              DeclaratorDecl *NewDecl) { +template<typename DeclT> +static bool SubstQualifier(Sema &SemaRef, const DeclT *OldDecl, DeclT *NewDecl, +                           const MultiLevelTemplateArgumentList &TemplateArgs) {    if (!OldDecl->getQualifierLoc())      return false; +  assert((NewDecl->getFriendObjectKind() || +          !OldDecl->getLexicalDeclContext()->isDependentContext()) && +         "non-friend with qualified name defined in dependent context"); +  Sema::ContextRAII SavedContext( +      SemaRef, +      const_cast<DeclContext *>(NewDecl->getFriendObjectKind() +                                    ? NewDecl->getLexicalDeclContext() +                                    : OldDecl->getLexicalDeclContext())); +    NestedNameSpecifierLoc NewQualifierLoc -    = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), -                                          TemplateArgs); +      = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), +                                            TemplateArgs);    if (!NewQualifierLoc)      return true; @@ -52,20 +62,14 @@ bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl,    return false;  } +bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, +                                              DeclaratorDecl *NewDecl) { +  return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs); +} +  bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,                                                TagDecl *NewDecl) { -  if (!OldDecl->getQualifierLoc()) -    return false; - -  NestedNameSpecifierLoc NewQualifierLoc -  = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), -                                        TemplateArgs); - -  if (!NewQualifierLoc) -    return true; - -  NewDecl->setQualifierInfo(NewQualifierLoc); -  return false; +  return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs);  }  // Include attribute instantiation code. @@ -129,6 +133,40 @@ static void instantiateDependentAlignedAttr(    }  } +static void instantiateDependentAssumeAlignedAttr( +    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, +    const AssumeAlignedAttr *Aligned, Decl *New) { +  // The alignment expression is a constant expression. +  EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); + +  Expr *E, *OE = nullptr; +  ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs); +  if (Result.isInvalid()) +    return; +  E = Result.getAs<Expr>(); + +  if (Aligned->getOffset()) { +    Result = S.SubstExpr(Aligned->getOffset(), TemplateArgs); +    if (Result.isInvalid()) +      return; +    OE = Result.getAs<Expr>(); +  } + +  S.AddAssumeAlignedAttr(Aligned->getLocation(), New, E, OE, +                         Aligned->getSpellingListIndex()); +} + +static void instantiateDependentAlignValueAttr( +    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, +    const AlignValueAttr *Aligned, Decl *New) { +  // The alignment expression is a constant expression. +  EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); +  ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs); +  if (!Result.isInvalid()) +    S.AddAlignValueAttr(Aligned->getLocation(), New, Result.getAs<Expr>(), +                        Aligned->getSpellingListIndex()); +} +  static void instantiateDependentEnableIfAttr(      Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,      const EnableIfAttr *A, const Decl *Tmpl, Decl *New) { @@ -176,6 +214,18 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,        continue;      } +    const AssumeAlignedAttr *AssumeAligned = dyn_cast<AssumeAlignedAttr>(TmplAttr); +    if (AssumeAligned) { +      instantiateDependentAssumeAlignedAttr(*this, TemplateArgs, AssumeAligned, New); +      continue; +    } + +    const AlignValueAttr *AlignValue = dyn_cast<AlignValueAttr>(TmplAttr); +    if (AlignValue) { +      instantiateDependentAlignValueAttr(*this, TemplateArgs, AlignValue, New); +      continue; +    } +      const EnableIfAttr *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr);      if (EnableIf && EnableIf->getCond()->isValueDependent()) {        instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl, @@ -183,6 +233,14 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,        continue;      } +    // Existing DLL attribute on the instantiation takes precedence. +    if (TmplAttr->getKind() == attr::DLLExport || +        TmplAttr->getKind() == attr::DLLImport) { +      if (New->hasAttr<DLLExportAttr>() || New->hasAttr<DLLImportAttr>()) { +        continue; +      } +    } +      assert(!TmplAttr->isPackExpansion());      if (TmplAttr->isLateParsed() && LateAttrs) {        // Late parsed attributes must be instantiated and attached after the @@ -207,6 +265,24 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,    }  } +/// Get the previous declaration of a declaration for the purposes of template +/// instantiation. If this finds a previous declaration, then the previous +/// declaration of the instantiation of D should be an instantiation of the +/// result of this function. +template<typename DeclT> +static DeclT *getPreviousDeclForInstantiation(DeclT *D) { +  DeclT *Result = D->getPreviousDecl(); + +  // If the declaration is within a class, and the previous declaration was +  // merged from a different definition of that class, then we don't have a +  // previous declaration for the purpose of template instantiation. +  if (Result && isa<CXXRecordDecl>(D->getDeclContext()) && +      D->getLexicalDeclContext() != Result->getLexicalDeclContext()) +    return nullptr; + +  return Result; +} +  Decl *  TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {    llvm_unreachable("Translation units cannot be instantiated"); @@ -293,7 +369,7 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,      }    } -  if (TypedefNameDecl *Prev = D->getPreviousDecl()) { +  if (TypedefNameDecl *Prev = getPreviousDeclForInstantiation(D)) {      NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,                                                         TemplateArgs);      if (!InstPrev) @@ -316,13 +392,15 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,  Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {    Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false); -  Owner->addDecl(Typedef); +  if (Typedef) +    Owner->addDecl(Typedef);    return Typedef;  }  Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {    Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true); -  Owner->addDecl(Typedef); +  if (Typedef) +    Owner->addDecl(Typedef);    return Typedef;  } @@ -340,7 +418,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {    TypeAliasDecl *Pattern = D->getTemplatedDecl();    TypeAliasTemplateDecl *PrevAliasTemplate = nullptr; -  if (Pattern->getPreviousDecl()) { +  if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) {      DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());      if (!Found.empty()) {        PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Found.front()); @@ -355,6 +433,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {    TypeAliasTemplateDecl *Inst      = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(),                                      D->getDeclName(), InstParams, AliasInst); +  AliasInst->setDescribedAliasTemplate(Inst);    if (PrevAliasTemplate)      Inst->setPreviousDecl(PrevAliasTemplate); @@ -578,11 +657,12 @@ Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) {    }    QualType T = cast<FieldDecl>(NamedChain[i-1])->getType(); -  IndirectFieldDecl* IndirectField -    = IndirectFieldDecl::Create(SemaRef.Context, Owner, D->getLocation(), -                                D->getIdentifier(), T, -                                NamedChain, D->getChainingSize()); +  IndirectFieldDecl *IndirectField = IndirectFieldDecl::Create( +      SemaRef.Context, Owner, D->getLocation(), D->getIdentifier(), T, +      NamedChain, D->getChainingSize()); +  for (const auto *Attr : D->attrs()) +    IndirectField->addAttr(Attr->clone(SemaRef.Context));    IndirectField->setImplicit(D->isImplicit());    IndirectField->setAccess(D->getAccess()); @@ -659,9 +739,9 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {  Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {    EnumDecl *PrevDecl = nullptr; -  if (D->getPreviousDecl()) { +  if (EnumDecl *PatternPrev = getPreviousDeclForInstantiation(D)) {      NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), -                                                   D->getPreviousDecl(), +                                                   PatternPrev,                                                     TemplateArgs);      if (!Prev) return nullptr;      PrevDecl = cast<EnumDecl>(Prev); @@ -823,7 +903,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {    CXXRecordDecl *PrevDecl = nullptr;    ClassTemplateDecl *PrevClassTemplate = nullptr; -  if (!isFriend && Pattern->getPreviousDecl()) { +  if (!isFriend && getPreviousDeclForInstantiation(Pattern)) {      DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());      if (!Found.empty()) {        PrevClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front()); @@ -1017,7 +1097,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {    VarDecl *Pattern = D->getTemplatedDecl();    VarTemplateDecl *PrevVarTemplate = nullptr; -  if (Pattern->getPreviousDecl()) { +  if (getPreviousDeclForInstantiation(Pattern)) {      DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());      if (!Found.empty())        PrevVarTemplate = dyn_cast<VarTemplateDecl>(Found.front()); @@ -1127,7 +1207,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {    if (!isFriend) {      Owner->addDecl(InstTemplate);    } else if (InstTemplate->getDeclContext()->isRecord() && -             !D->getPreviousDecl()) { +             !getPreviousDeclForInstantiation(D)) {      SemaRef.CheckFriendAccess(InstTemplate);    } @@ -1138,9 +1218,9 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {    CXXRecordDecl *PrevDecl = nullptr;    if (D->isInjectedClassName())      PrevDecl = cast<CXXRecordDecl>(Owner); -  else if (D->getPreviousDecl()) { +  else if (CXXRecordDecl *PatternPrev = getPreviousDeclForInstantiation(D)) {      NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), -                                                   D->getPreviousDecl(), +                                                   PatternPrev,                                                     TemplateArgs);      if (!Prev) return nullptr;      PrevDecl = cast<CXXRecordDecl>(Prev); @@ -1191,6 +1271,9 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {      SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,                                      TSK_ImplicitInstantiation);    } + +  SemaRef.DiagnoseUnusedNestedTypedefs(Record); +    return Record;  } @@ -2201,7 +2284,8 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {      if (CheckRedeclaration) {        if (SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev, PrevDecl))          continue; -    } else if (UsingShadowDecl *OldPrev = Shadow->getPreviousDecl()) { +    } else if (UsingShadowDecl *OldPrev = +                   getPreviousDeclForInstantiation(Shadow)) {        PrevDecl = cast_or_null<UsingShadowDecl>(SemaRef.FindInstantiatedDecl(            Shadow->getLocation(), OldPrev, TemplateArgs));      } @@ -2276,8 +2360,10 @@ Decl * TemplateDeclInstantiator  Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(                                       ClassScopeFunctionSpecializationDecl *Decl) {    CXXMethodDecl *OldFD = Decl->getSpecialization(); -  CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, -                                                                nullptr, true)); +  CXXMethodDecl *NewFD = +    cast_or_null<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, nullptr, true)); +  if (!NewFD) +    return nullptr;    LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,                          Sema::ForRedeclaration); @@ -2976,7 +3062,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,  /// Introduce the instantiated function parameters into the local  /// instantiation scope, and set the parameter names to those used  /// in the template. -static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, +static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,                                               const FunctionDecl *PatternDecl,                                               LocalInstantiationScope &Scope,                             const MultiLevelTemplateArgumentList &TemplateArgs) { @@ -2987,15 +3073,22 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,        // Simple case: not a parameter pack.        assert(FParamIdx < Function->getNumParams());        ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); +      FunctionParam->setDeclName(PatternParam->getDeclName());        // If the parameter's type is not dependent, update it to match the type        // in the pattern. They can differ in top-level cv-qualifiers, and we want        // the pattern's type here. If the type is dependent, they can't differ, -      // per core issue 1668. +      // per core issue 1668. Substitute into the type from the pattern, in case +      // it's instantiation-dependent.        // FIXME: Updating the type to work around this is at best fragile. -      if (!PatternDecl->getType()->isDependentType()) -        FunctionParam->setType(PatternParam->getType()); +      if (!PatternDecl->getType()->isDependentType()) { +        QualType T = S.SubstType(PatternParam->getType(), TemplateArgs, +                                 FunctionParam->getLocation(), +                                 FunctionParam->getDeclName()); +        if (T.isNull()) +          return true; +        FunctionParam->setType(T); +      } -      FunctionParam->setDeclName(PatternParam->getDeclName());        Scope.InstantiatedLocal(PatternParam, FunctionParam);        ++FParamIdx;        continue; @@ -3007,137 +3100,27 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,        = S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs);      assert(NumArgumentsInExpansion &&             "should only be called when all template arguments are known"); +    QualType PatternType = +        PatternParam->getType()->castAs<PackExpansionType>()->getPattern();      for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {        ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); -      if (!PatternDecl->getType()->isDependentType()) -        FunctionParam->setType(PatternParam->getType()); -        FunctionParam->setDeclName(PatternParam->getDeclName()); -      Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); -      ++FParamIdx; -    } -  } -} - -static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, -                                     const FunctionProtoType *Proto, -                           const MultiLevelTemplateArgumentList &TemplateArgs) { -  assert(Proto->getExceptionSpecType() != EST_Uninstantiated); - -  // C++11 [expr.prim.general]p3: -  //   If a declaration declares a member function or member function  -  //   template of a class X, the expression this is a prvalue of type  -  //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq -  //   and the end of the function-definition, member-declarator, or  -  //   declarator.     -  CXXRecordDecl *ThisContext = nullptr; -  unsigned ThisTypeQuals = 0; -  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(New)) { -    ThisContext = Method->getParent(); -    ThisTypeQuals = Method->getTypeQualifiers(); -  } -  Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals, -                                   SemaRef.getLangOpts().CPlusPlus11); - -  // The function has an exception specification or a "noreturn" -  // attribute. Substitute into each of the exception types. -  SmallVector<QualType, 4> Exceptions; -  for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) { -    // FIXME: Poor location information! -    if (const PackExpansionType *PackExpansion -          = Proto->getExceptionType(I)->getAs<PackExpansionType>()) { -      // We have a pack expansion. Instantiate it. -      SmallVector<UnexpandedParameterPack, 2> Unexpanded; -      SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), -                                              Unexpanded); -      assert(!Unexpanded.empty() && -             "Pack expansion without parameter packs?"); - -      bool Expand = false; -      bool RetainExpansion = false; -      Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); -      if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), -                                                  SourceRange(), -                                                  Unexpanded, -                                                  TemplateArgs, -                                                  Expand, -                                                  RetainExpansion, -                                                  NumExpansions)) -        break; - -      if (!Expand) { -        // We can't expand this pack expansion into separate arguments yet; -        // just substitute into the pattern and create a new pack expansion -        // type. -        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); -        QualType T = SemaRef.SubstType(PackExpansion->getPattern(), -                                       TemplateArgs, -                                     New->getLocation(), New->getDeclName()); +      if (!PatternDecl->getType()->isDependentType()) { +        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, Arg); +        QualType T = S.SubstType(PatternType, TemplateArgs, +                                 FunctionParam->getLocation(), +                                 FunctionParam->getDeclName());          if (T.isNull()) -          break; - -        T = SemaRef.Context.getPackExpansionType(T, NumExpansions); -        Exceptions.push_back(T); -        continue; -      } - -      // Substitute into the pack expansion pattern for each template -      bool Invalid = false; -      for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { -        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); - -        QualType T = SemaRef.SubstType(PackExpansion->getPattern(), -                                       TemplateArgs, -                                     New->getLocation(), New->getDeclName()); -        if (T.isNull()) { -          Invalid = true; -          break; -        } - -        Exceptions.push_back(T); +          return true; +        FunctionParam->setType(T);        } -      if (Invalid) -        break; - -      continue; -    } - -    QualType T -      = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs, -                          New->getLocation(), New->getDeclName()); -    if (T.isNull() || -        SemaRef.CheckSpecifiedExceptionType(T, New->getLocation())) -      continue; - -    Exceptions.push_back(T); -  } -  Expr *NoexceptExpr = nullptr; -  if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) { -    EnterExpressionEvaluationContext Unevaluated(SemaRef, -                                                 Sema::ConstantEvaluated); -    ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); -    if (E.isUsable()) -      E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); - -    if (E.isUsable()) { -      NoexceptExpr = E.get(); -      if (!NoexceptExpr->isTypeDependent() && -          !NoexceptExpr->isValueDependent()) -        NoexceptExpr -          = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr, -              nullptr, diag::err_noexcept_needs_constant_expression, -              /*AllowFold*/ false).get(); +      Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); +      ++FParamIdx;      }    } -  FunctionProtoType::ExtProtoInfo EPI; -  EPI.ExceptionSpecType = Proto->getExceptionSpecType(); -  EPI.NumExceptions = Exceptions.size(); -  EPI.Exceptions = Exceptions.data(); -  EPI.NoexceptExpr = NoexceptExpr; - -  SemaRef.UpdateExceptionSpec(New, EPI); +  return false;  }  void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, @@ -3151,9 +3134,7 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,    if (Inst.isInvalid()) {      // We hit the instantiation depth limit. Clear the exception specification      // so that our callers don't have to cope with EST_Uninstantiated. -    FunctionProtoType::ExtProtoInfo EPI; -    EPI.ExceptionSpecType = EST_None; -    UpdateExceptionSpec(Decl, EPI); +    UpdateExceptionSpec(Decl, EST_None);      return;    } @@ -3166,11 +3147,14 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,      getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true);    FunctionDecl *Template = Proto->getExceptionSpecTemplate(); -  addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs); +  if (addInstantiatedParametersToScope(*this, Decl, Template, Scope, +                                       TemplateArgs)) { +    UpdateExceptionSpec(Decl, EST_None); +    return; +  } -  ::InstantiateExceptionSpec(*this, Decl, -                             Template->getType()->castAs<FunctionProtoType>(), -                             TemplateArgs); +  SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(), +                     TemplateArgs);  }  /// \brief Initializes the common fields of an instantiation function @@ -3218,14 +3202,14 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,      // DR1330: In C++11, defer instantiation of a non-trivial      // exception specification.      if (SemaRef.getLangOpts().CPlusPlus11 && -        EPI.ExceptionSpecType != EST_None && -        EPI.ExceptionSpecType != EST_DynamicNone && -        EPI.ExceptionSpecType != EST_BasicNoexcept) { +        EPI.ExceptionSpec.Type != EST_None && +        EPI.ExceptionSpec.Type != EST_DynamicNone && +        EPI.ExceptionSpec.Type != EST_BasicNoexcept) {        FunctionDecl *ExceptionSpecTemplate = Tmpl; -      if (EPI.ExceptionSpecType == EST_Uninstantiated) -        ExceptionSpecTemplate = EPI.ExceptionSpecTemplate; +      if (EPI.ExceptionSpec.Type == EST_Uninstantiated) +        ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate;        ExceptionSpecificationType NewEST = EST_Uninstantiated; -      if (EPI.ExceptionSpecType == EST_Unevaluated) +      if (EPI.ExceptionSpec.Type == EST_Unevaluated)          NewEST = EST_Unevaluated;        // Mark the function has having an uninstantiated exception specification. @@ -3233,13 +3217,13 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,          = New->getType()->getAs<FunctionProtoType>();        assert(NewProto && "Template instantiation without function prototype?");        EPI = NewProto->getExtProtoInfo(); -      EPI.ExceptionSpecType = NewEST; -      EPI.ExceptionSpecDecl = New; -      EPI.ExceptionSpecTemplate = ExceptionSpecTemplate; +      EPI.ExceptionSpec.Type = NewEST; +      EPI.ExceptionSpec.SourceDecl = New; +      EPI.ExceptionSpec.SourceTemplate = ExceptionSpecTemplate;        New->setType(SemaRef.Context.getFunctionType(            NewProto->getReturnType(), NewProto->getParamTypes(), EPI));      } else { -      ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs); +      SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);      }    } @@ -3322,6 +3306,20 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,      return;    } +  // If we're performing recursive template instantiation, create our own +  // queue of pending implicit instantiations that we will instantiate later, +  // while we're still within our own instantiation context. +  // This has to happen before LateTemplateParser below is called, so that +  // it marks vtables used in late parsed templates as used. +  SavePendingLocalImplicitInstantiationsRAII +      SavedPendingLocalImplicitInstantiations(*this); +  std::unique_ptr<SavePendingInstantiationsAndVTableUsesRAII> +      SavePendingInstantiationsAndVTableUses; +  if (Recursive) { +    SavePendingInstantiationsAndVTableUses.reset( +        new SavePendingInstantiationsAndVTableUsesRAII(*this)); +  } +    // Call the LateTemplateParser callback if there is a need to late parse    // a templated function definition.    if (!Pattern && PatternDecl->isLateTemplateParsed() && @@ -3353,6 +3351,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,        Function->setInvalidDecl();      } else if (Function->getTemplateSpecializationKind()                   == TSK_ExplicitInstantiationDefinition) { +      assert(!Recursive);        PendingInstantiations.push_back(          std::make_pair(Function, PointOfInstantiation));      } @@ -3389,18 +3388,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    // Copy the inner loc start from the pattern.    Function->setInnerLocStart(PatternDecl->getInnerLocStart()); -  // If we're performing recursive template instantiation, create our own -  // queue of pending implicit instantiations that we will instantiate later, -  // while we're still within our own instantiation context. -  SmallVector<VTableUse, 16> SavedVTableUses; -  std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; -  SavePendingLocalImplicitInstantiationsRAII -      SavedPendingLocalImplicitInstantiations(*this); -  if (Recursive) { -    VTableUses.swap(SavedVTableUses); -    PendingInstantiations.swap(SavedPendingInstantiations); -  } -    EnterExpressionEvaluationContext EvalContext(*this,                                                 Sema::PotentiallyEvaluated); @@ -3417,17 +3404,24 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    if (PatternDecl->isDefaulted())      SetDeclDefaulted(Function, PatternDecl->getLocation());    else { +    MultiLevelTemplateArgumentList TemplateArgs = +      getTemplateInstantiationArgs(Function, nullptr, false, PatternDecl); + +    // Substitute into the qualifier; we can get a substitution failure here +    // through evil use of alias templates. +    // FIXME: Is CurContext correct for this? Should we go to the (instantiation +    // of the) lexical context of the pattern? +    SubstQualifier(*this, PatternDecl, Function, TemplateArgs); +      ActOnStartOfFunctionDef(nullptr, Function);      // Enter the scope of this instantiation. We don't use      // PushDeclContext because we don't have a scope.      Sema::ContextRAII savedContext(*this, Function); -    MultiLevelTemplateArgumentList TemplateArgs = -      getTemplateInstantiationArgs(Function, nullptr, false, PatternDecl); - -    addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope, -                                     TemplateArgs); +    if (addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope, +                                         TemplateArgs)) +      return;      // If this is a constructor, instantiate the member initializers.      if (const CXXConstructorDecl *Ctor = @@ -3469,15 +3463,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,      // instantiation of this template.      PerformPendingInstantiations(); -    // Restore the set of pending vtables. -    assert(VTableUses.empty() && -           "VTableUses should be empty before it is discarded."); -    VTableUses.swap(SavedVTableUses); - -    // Restore the set of pending implicit instantiations. -    assert(PendingInstantiations.empty() && -           "PendingInstantiations should be empty before it is discarded."); -    PendingInstantiations.swap(SavedPendingInstantiations); +    // Restore PendingInstantiations and VTableUses. +    SavePendingInstantiationsAndVTableUses.reset();    }  } @@ -3651,7 +3638,7 @@ void Sema::BuildVariableInstantiation(    // Diagnose unused local variables with dependent types, where the diagnostic    // will have been deferred.    if (!NewVar->isInvalidDecl() && -      NewVar->getDeclContext()->isFunctionOrMethod() && !NewVar->isUsed() && +      NewVar->getDeclContext()->isFunctionOrMethod() &&        OldVar->getType()->isDependentType())      DiagnoseUnusedDecl(NewVar);  } @@ -3793,11 +3780,11 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,        // If we're performing recursive template instantiation, create our own        // queue of pending implicit instantiations that we will instantiate        // later, while we're still within our own instantiation context. -      SmallVector<VTableUse, 16> SavedVTableUses; -      std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; +      std::unique_ptr<SavePendingInstantiationsAndVTableUsesRAII> +          SavePendingInstantiationsAndVTableUses;        if (Recursive) { -        VTableUses.swap(SavedVTableUses); -        PendingInstantiations.swap(SavedPendingInstantiations); +        SavePendingInstantiationsAndVTableUses.reset( +            new SavePendingInstantiationsAndVTableUsesRAII(*this));        }        LocalInstantiationScope Local(*this); @@ -3825,15 +3812,8 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,          // instantiation of this template.          PerformPendingInstantiations(); -        // Restore the set of pending vtables. -        assert(VTableUses.empty() && -               "VTableUses should be empty before it is discarded."); -        VTableUses.swap(SavedVTableUses); - -        // Restore the set of pending implicit instantiations. -        assert(PendingInstantiations.empty() && -               "PendingInstantiations should be empty before it is discarded."); -        PendingInstantiations.swap(SavedPendingInstantiations); +        // Restore PendingInstantiations and VTableUses. +        SavePendingInstantiationsAndVTableUses.reset();        }      } @@ -3917,13 +3897,13 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,    // If we're performing recursive template instantiation, create our own    // queue of pending implicit instantiations that we will instantiate later,    // while we're still within our own instantiation context. -  SmallVector<VTableUse, 16> SavedVTableUses; -  std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;    SavePendingLocalImplicitInstantiationsRAII        SavedPendingLocalImplicitInstantiations(*this); +  std::unique_ptr<SavePendingInstantiationsAndVTableUsesRAII> +      SavePendingInstantiationsAndVTableUses;    if (Recursive) { -    VTableUses.swap(SavedVTableUses); -    PendingInstantiations.swap(SavedPendingInstantiations); +    SavePendingInstantiationsAndVTableUses.reset( +        new SavePendingInstantiationsAndVTableUsesRAII(*this));    }    // Enter the scope of this instantiation. We don't use @@ -3990,15 +3970,8 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,      // instantiation of this template.      PerformPendingInstantiations(); -    // Restore the set of pending vtables. -    assert(VTableUses.empty() && -           "VTableUses should be empty before it is discarded."); -    VTableUses.swap(SavedVTableUses); - -    // Restore the set of pending implicit instantiations. -    assert(PendingInstantiations.empty() && -           "PendingInstantiations should be empty before it is discarded."); -    PendingInstantiations.swap(SavedPendingInstantiations); +    // Restore PendingInstantiations and VTableUses. +    SavePendingInstantiationsAndVTableUses.reset();    }  } @@ -4235,25 +4208,26 @@ static bool isInstantiationOf(EnumDecl *Pattern,  static bool isInstantiationOf(UsingShadowDecl *Pattern,                                UsingShadowDecl *Instance,                                ASTContext &C) { -  return C.getInstantiatedFromUsingShadowDecl(Instance) == Pattern; +  return declaresSameEntity(C.getInstantiatedFromUsingShadowDecl(Instance), +                            Pattern);  }  static bool isInstantiationOf(UsingDecl *Pattern,                                UsingDecl *Instance,                                ASTContext &C) { -  return C.getInstantiatedFromUsingDecl(Instance) == Pattern; +  return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);  }  static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern,                                UsingDecl *Instance,                                ASTContext &C) { -  return C.getInstantiatedFromUsingDecl(Instance) == Pattern; +  return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);  }  static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern,                                UsingDecl *Instance,                                ASTContext &C) { -  return C.getInstantiatedFromUsingDecl(Instance) == Pattern; +  return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);  }  static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, @@ -4319,8 +4293,8 @@ static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {    if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) {      if (!Field->getDeclName()) {        // This is an unnamed field. -      return Ctx.getInstantiatedFromUnnamedFieldDecl(Field) == -        cast<FieldDecl>(D); +      return declaresSameEntity(Ctx.getInstantiatedFromUnnamedFieldDecl(Field), +                                cast<FieldDecl>(D));      }    } @@ -4412,17 +4386,17 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,        (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {      // D is a local of some kind. Look into the map of local      // declarations to their instantiations. -    typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; -    llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found -      = CurrentInstantiationScope->findInstantiationOf(D); - -    if (Found) { -      if (Decl *FD = Found->dyn_cast<Decl *>()) -        return cast<NamedDecl>(FD); - -      int PackIdx = ArgumentPackSubstitutionIndex; -      assert(PackIdx != -1 && "found declaration pack but not pack expanding"); -      return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]); +    if (CurrentInstantiationScope) { +      if (auto Found = CurrentInstantiationScope->findInstantiationOf(D)) { +        if (Decl *FD = Found->dyn_cast<Decl *>()) +          return cast<NamedDecl>(FD); + +        int PackIdx = ArgumentPackSubstitutionIndex; +        assert(PackIdx != -1 && +               "found declaration pack but not pack expanding"); +        typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; +        return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]); +      }      }      // If we're performing a partial substitution during template argument diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 8e4ce0d9da6f..e4fab71d995b 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -197,6 +197,20 @@ namespace {    };  } +/// \brief Determine whether it's possible for an unexpanded parameter pack to +/// be valid in this location. This only happens when we're in a declaration +/// that is nested within an expression that could be expanded, such as a +/// lambda-expression within a function call. +/// +/// This is conservatively correct, but may claim that some unexpanded packs are +/// permitted when they are not. +bool Sema::isUnexpandedParameterPackPermitted() { +  for (auto *SI : FunctionScopes) +    if (isa<sema::LambdaScopeInfo>(SI)) +      return true; +  return false; +} +  /// \brief Diagnose all of the unexpanded parameter packs in the given  /// vector.  bool @@ -230,7 +244,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,      else        Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier(); -    if (Name && NamesKnown.insert(Name)) +    if (Name && NamesKnown.insert(Name).second)        Names.push_back(Name);      if (Unexpanded[I].second.isValid()) @@ -733,24 +747,48 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {    case TST_error:      break;    } -   +    for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {      const DeclaratorChunk &Chunk = D.getTypeObject(I);      switch (Chunk.Kind) {      case DeclaratorChunk::Pointer:      case DeclaratorChunk::Reference:      case DeclaratorChunk::Paren: +    case DeclaratorChunk::BlockPointer:        // These declarator chunks cannot contain any parameter packs.        break;      case DeclaratorChunk::Array: +      if (Chunk.Arr.NumElts && +          Chunk.Arr.NumElts->containsUnexpandedParameterPack()) +        return true; +      break;      case DeclaratorChunk::Function: -    case DeclaratorChunk::BlockPointer: -      // Syntactically, these kinds of declarator chunks all come after the -      // declarator-id (conceptually), so the parser should not invoke this -      // routine at this time. -      llvm_unreachable("Could not have seen this kind of declarator chunk"); -         +      for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { +        ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param); +        QualType ParamTy = Param->getType(); +        assert(!ParamTy.isNull() && "Couldn't parse type?"); +        if (ParamTy->containsUnexpandedParameterPack()) return true; +      } + +      if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) { +        for (unsigned i = 0; i != Chunk.Fun.NumExceptions; ++i) { +          if (Chunk.Fun.Exceptions[i] +                  .Ty.get() +                  ->containsUnexpandedParameterPack()) +            return true; +        } +      } else if (Chunk.Fun.getExceptionSpecType() == EST_ComputedNoexcept && +                 Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack()) +        return true; + +      if (Chunk.Fun.hasTrailingReturnType()) { +        QualType T = Chunk.Fun.getTrailingReturnType().get(); +	if (!T.isNull() && T->containsUnexpandedParameterPack()) +	  return true; +      } +      break; +      case DeclaratorChunk::MemberPointer:        if (Chunk.Mem.Scope().getScopeRep() &&            Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) @@ -800,7 +838,6 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,    LookupName(R, S);    NamedDecl *ParameterPack = nullptr; -  ParameterPackValidatorCCC Validator;    switch (R.getResultKind()) {    case LookupResult::Found:      ParameterPack = R.getFoundDecl(); @@ -808,9 +845,10 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,    case LookupResult::NotFound:    case LookupResult::NotFoundInCurrentInstantiation: -    if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), -                                               R.getLookupKind(), S, nullptr, -                                               Validator, CTK_ErrorRecovery)) { +    if (TypoCorrection Corrected = +            CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, +                        llvm::make_unique<ParameterPackValidatorCCC>(), +                        CTK_ErrorRecovery)) {        diagnoseTypo(Corrected,                     PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,                     PDiag(diag::note_parameter_pack_here)); @@ -897,3 +935,108 @@ Sema::getTemplateArgumentPackExpansionPattern(    llvm_unreachable("Invalid TemplateArgument Kind!");  } + +static void CheckFoldOperand(Sema &S, Expr *E) { +  if (!E) +    return; + +  E = E->IgnoreImpCasts(); +  if (isa<BinaryOperator>(E) || isa<AbstractConditionalOperator>(E)) { +    S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand) +        << E->getSourceRange() +        << FixItHint::CreateInsertion(E->getLocStart(), "(") +        << FixItHint::CreateInsertion(E->getLocEnd(), ")"); +  } +} + +ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, +                                  tok::TokenKind Operator, +                                  SourceLocation EllipsisLoc, Expr *RHS, +                                  SourceLocation RParenLoc) { +  // LHS and RHS must be cast-expressions. We allow an arbitrary expression +  // in the parser and reduce down to just cast-expressions here. +  CheckFoldOperand(*this, LHS); +  CheckFoldOperand(*this, RHS); + +  // [expr.prim.fold]p3: +  //   In a binary fold, op1 and op2 shall be the same fold-operator, and +  //   either e1 shall contain an unexpanded parameter pack or e2 shall contain +  //   an unexpanded parameter pack, but not both. +  if (LHS && RHS && +      LHS->containsUnexpandedParameterPack() == +          RHS->containsUnexpandedParameterPack()) { +    return Diag(EllipsisLoc, +                LHS->containsUnexpandedParameterPack() +                    ? diag::err_fold_expression_packs_both_sides +                    : diag::err_pack_expansion_without_parameter_packs) +        << LHS->getSourceRange() << RHS->getSourceRange(); +  } + +  // [expr.prim.fold]p2: +  //   In a unary fold, the cast-expression shall contain an unexpanded +  //   parameter pack. +  if (!LHS || !RHS) { +    Expr *Pack = LHS ? LHS : RHS; +    assert(Pack && "fold expression with neither LHS nor RHS"); +    if (!Pack->containsUnexpandedParameterPack()) +      return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) +             << Pack->getSourceRange(); +  } + +  BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator); +  return BuildCXXFoldExpr(LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc); +} + +ExprResult Sema::BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, +                                  BinaryOperatorKind Operator, +                                  SourceLocation EllipsisLoc, Expr *RHS, +                                  SourceLocation RParenLoc) { +  return new (Context) CXXFoldExpr(Context.DependentTy, LParenLoc, LHS, +                                   Operator, EllipsisLoc, RHS, RParenLoc); +} + +ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, +                                       BinaryOperatorKind Operator) { +  // [temp.variadic]p9: +  //   If N is zero for a unary fold-expression, the value of the expression is +  //       *   ->  1 +  //       +   ->  int() +  //       &   ->  -1 +  //       |   ->  int() +  //       &&  ->  true +  //       ||  ->  false +  //       ,   ->  void() +  //   if the operator is not listed [above], the instantiation is ill-formed. +  // +  // Note that we need to use something like int() here, not merely 0, to +  // prevent the result from being a null pointer constant. +  QualType ScalarType; +  switch (Operator) { +  case BO_Add: +    ScalarType = Context.IntTy; +    break; +  case BO_Mul: +    return ActOnIntegerConstant(EllipsisLoc, 1); +  case BO_Or: +    ScalarType = Context.IntTy; +    break; +  case BO_And: +    return CreateBuiltinUnaryOp(EllipsisLoc, UO_Minus, +                                ActOnIntegerConstant(EllipsisLoc, 1).get()); +  case BO_LOr: +    return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false); +  case BO_LAnd: +    return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true); +  case BO_Comma: +    ScalarType = Context.VoidTy; +    break; + +  default: +    return Diag(EllipsisLoc, diag::err_fold_expression_empty) +        << BinaryOperator::getOpcodeStr(Operator); +  } + +  return new (Context) CXXScalarValueInitExpr( +      ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc), +      EllipsisLoc); +} diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index be1191c1e8e0..0f96a1cbce35 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -107,6 +107,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,      case AttributeList::AT_StdCall: \      case AttributeList::AT_ThisCall: \      case AttributeList::AT_Pascal: \ +    case AttributeList::AT_VectorCall: \      case AttributeList::AT_MSABI: \      case AttributeList::AT_SysVABI: \      case AttributeList::AT_Regparm: \ @@ -660,26 +661,27 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,    // ...and *prepend* it to the declarator.    SourceLocation NoLoc;    declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction( -                             /*HasProto=*/true, -                             /*IsAmbiguous=*/false, -                             /*LParenLoc=*/NoLoc, -                             /*ArgInfo=*/nullptr, -                             /*NumArgs=*/0, -                             /*EllipsisLoc=*/NoLoc, -                             /*RParenLoc=*/NoLoc, -                             /*TypeQuals=*/0, -                             /*RefQualifierIsLvalueRef=*/true, -                             /*RefQualifierLoc=*/NoLoc, -                             /*ConstQualifierLoc=*/NoLoc, -                             /*VolatileQualifierLoc=*/NoLoc, -                             /*MutableLoc=*/NoLoc, -                             EST_None, -                             /*ESpecLoc=*/NoLoc, -                             /*Exceptions=*/nullptr, -                             /*ExceptionRanges=*/nullptr, -                             /*NumExceptions=*/0, -                             /*NoexceptExpr=*/nullptr, -                             loc, loc, declarator)); +      /*HasProto=*/true, +      /*IsAmbiguous=*/false, +      /*LParenLoc=*/NoLoc, +      /*ArgInfo=*/nullptr, +      /*NumArgs=*/0, +      /*EllipsisLoc=*/NoLoc, +      /*RParenLoc=*/NoLoc, +      /*TypeQuals=*/0, +      /*RefQualifierIsLvalueRef=*/true, +      /*RefQualifierLoc=*/NoLoc, +      /*ConstQualifierLoc=*/NoLoc, +      /*VolatileQualifierLoc=*/NoLoc, +      /*RestrictQualifierLoc=*/NoLoc, +      /*MutableLoc=*/NoLoc, EST_None, +      /*ESpecLoc=*/NoLoc, +      /*Exceptions=*/nullptr, +      /*ExceptionRanges=*/nullptr, +      /*NumExceptions=*/0, +      /*NoexceptExpr=*/nullptr, +      /*ExceptionSpecTokens=*/nullptr, +      loc, loc, declarator));    // For consistency, make sure the state still has us as processing    // the decl spec. @@ -763,7 +765,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {      // is inferred from the return statements inside the block.      // The declspec is always missing in a lambda expr context; it is either      // specified with a trailing return type or inferred. -    if (S.getLangOpts().CPlusPlus1y && +    if (S.getLangOpts().CPlusPlus14 &&          declarator.getContext() == Declarator::LambdaExprContext) {        // In C++1y, a lambda's implicit return type is 'auto'.        Result = Context.getAutoDeductType(); @@ -1005,16 +1007,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {        const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth;        const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size();        const bool IsParameterPack = declarator.hasEllipsis(); -       -      // Create a name for the invented template parameter type. -      std::string InventedTemplateParamName = "$auto-"; -      llvm::raw_string_ostream ss(InventedTemplateParamName); -      ss << TemplateParameterDepth;  -      ss << "-" << AutoParameterPosition; -      ss.flush(); - -      IdentifierInfo& TemplateParamII = Context.Idents.get( -                                        InventedTemplateParamName.c_str()); +        // Turns out we must create the TemplateTypeParmDecl here to         // retrieve the corresponding template parameter type.         TemplateTypeParmDecl *CorrespondingTemplateParam = @@ -1029,11 +1022,11 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {          /*NameLoc*/ declarator.getLocStart(),            TemplateParameterDepth,           AutoParameterPosition,  // our template param index  -        /* Identifier*/ &TemplateParamII, false, IsParameterPack); +        /* Identifier*/ nullptr, false, IsParameterPack);        LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam);        // Replace the 'auto' in the function parameter with this invented         // template type parameter. -      Result = QualType(CorrespondingTemplateParam->getTypeForDecl(), 0);   +      Result = QualType(CorrespondingTemplateParam->getTypeForDecl(), 0);      } else {        Result = Context.getAutoType(QualType(), /*decltype(auto)*/false, false);      } @@ -1107,8 +1100,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {          S.Diag(DS.getConstSpecLoc(), diag::warn_typecheck_function_qualifiers)            << Result << DS.getSourceRange();        else if (TypeQuals & DeclSpec::TQ_volatile) -        S.Diag(DS.getVolatileSpecLoc(), diag::warn_typecheck_function_qualifiers) -          << Result << DS.getSourceRange(); +        S.Diag(DS.getVolatileSpecLoc(), +               diag::warn_typecheck_function_qualifiers) +            << Result << DS.getSourceRange();        else {          assert((TypeQuals & (DeclSpec::TQ_restrict | DeclSpec::TQ_atomic)) &&                 "Has CVRA quals but not C, V, R, or A?"); @@ -1174,6 +1168,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {        Result = Qualified;    } +  assert(!Result.isNull() && "This function should not return a null type");    return Result;  } @@ -1186,6 +1181,9 @@ static std::string getPrintableNameForEntity(DeclarationName Entity) {  QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,                                    Qualifiers Qs, const DeclSpec *DS) { +  if (T.isNull()) +    return QualType(); +    // Enforce C99 6.7.3p2: "Types other than pointer types derived from    // object or incomplete types shall not be restrict-qualified."    if (Qs.hasRestrict()) { @@ -1224,6 +1222,9 @@ QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,  QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,                                    unsigned CVRA, const DeclSpec *DS) { +  if (T.isNull()) +    return QualType(); +    // Convert from DeclSpec::TQ to Qualifiers::TQ by just dropping TQ_atomic.    unsigned CVR = CVRA & ~DeclSpec::TQ_atomic; @@ -1746,7 +1747,7 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {    }    // Functions cannot return half FP. -  if (T->isHalfType()) { +  if (T->isHalfType() && !getLangOpts().HalfArgsAndReturns) {      Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 1 <<        FixItHint::CreateInsertion(Loc, "*");      return true; @@ -1776,7 +1777,7 @@ QualType Sema::BuildFunctionType(QualType T,      if (ParamType->isVoidType()) {        Diag(Loc, diag::err_param_with_void_type);        Invalid = true; -    } else if (ParamType->isHalfType()) { +    } else if (ParamType->isHalfType() && !getLangOpts().HalfArgsAndReturns) {        // Disallow half FP arguments.        Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 0 <<          FixItHint::CreateInsertion(Loc, "*"); @@ -2175,7 +2176,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,        Error = 0;          break;      case Declarator::LambdaExprParameterContext: -      if (!(SemaRef.getLangOpts().CPlusPlus1y  +      if (!(SemaRef.getLangOpts().CPlusPlus14                 && D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto))          Error = 14;        break; @@ -2208,11 +2209,11 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,        Error = 10; // Type alias        break;      case Declarator::TrailingReturnContext: -      if (!SemaRef.getLangOpts().CPlusPlus1y) +      if (!SemaRef.getLangOpts().CPlusPlus14)          Error = 11; // Function return type        break;      case Declarator::ConversionIdContext: -      if (!SemaRef.getLangOpts().CPlusPlus1y) +      if (!SemaRef.getLangOpts().CPlusPlus14)          Error = 12; // conversion-type-id        break;      case Declarator::TypeNameContext: @@ -2332,6 +2333,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,      }    } +  assert(!T.isNull() && "This function should not return a null type");    return T;  } @@ -2481,7 +2483,8 @@ getCCForDeclaratorChunk(Sema &S, Declarator &D,  static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,                                                  QualType declSpecType,                                                  TypeSourceInfo *TInfo) { - +  // The TypeSourceInfo that this function returns will not be a null type. +  // If there is an error, this function will fill in a dummy type as fallback.    QualType T = declSpecType;    Declarator &D = state.getDeclarator();    Sema &S = state.getSema(); @@ -2697,7 +2700,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,          // and not, for instance, a pointer to a function.          if (D.getDeclSpec().containsPlaceholderType() &&              !FTI.hasTrailingReturnType() && chunkIndex == 0 && -            !S.getLangOpts().CPlusPlus1y) { +            !S.getLangOpts().CPlusPlus14) {            S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),                   D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto                       ? diag::err_auto_missing_trailing_return @@ -2751,7 +2754,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,              S.Diag(D.getIdentifierLoc(), diag::err_opencl_half_return) << T;              D.setInvalidType(true);            }  -        } else { +        } else if (!S.getLangOpts().HalfArgsAndReturns) {            S.Diag(D.getIdentifierLoc(),              diag::err_parameters_retval_cannot_have_fp16_type) << 1;            D.setInvalidType(true); @@ -2941,7 +2944,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,                  D.setInvalidType();                  Param->setInvalidDecl();                } -            } else { +            } else if (!S.getLangOpts().HalfArgsAndReturns) {                S.Diag(Param->getLocation(),                  diag::err_parameters_retval_cannot_have_fp16_type) << 0;                D.setInvalidType(); @@ -2989,12 +2992,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,            NoexceptExpr = FTI.NoexceptExpr;          } -        S.checkExceptionSpecification(FTI.getExceptionSpecType(), +        S.checkExceptionSpecification(D.isFunctionDeclarationContext(), +                                      FTI.getExceptionSpecType(),                                        DynamicExceptions,                                        DynamicExceptionRanges,                                        NoexceptExpr,                                        Exceptions, -                                      EPI); +                                      EPI.ExceptionSpec);          T = Context.getFunctionType(T, ParamTys, EPI);        } @@ -3021,6 +3025,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,          case NestedNameSpecifier::Namespace:          case NestedNameSpecifier::NamespaceAlias:          case NestedNameSpecifier::Global: +        case NestedNameSpecifier::Super:            llvm_unreachable("Nested-name-specifier must name a type");          case NestedNameSpecifier::TypeSpec: @@ -3044,7 +3049,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,        }        if (!ClsType.isNull()) -        T = S.BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier()); +        T = S.BuildMemberPointerType(T, ClsType, DeclType.Loc, +                                     D.getIdentifier());        if (T.isNull()) {          T = Context.IntTy;          D.setInvalidType(true); @@ -3064,6 +3070,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,        processTypeAttrs(state, T, TAL_DeclChunk, attrs);    } +  assert(!T.isNull() && "T must not be null after this point"); +    if (LangOpts.CPlusPlus && T->isFunctionType()) {      const FunctionProtoType *FnTy = T->getAs<FunctionProtoType>();      assert(FnTy && "Why oh why is there not a FunctionProtoType here?"); @@ -3120,9 +3128,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,            RemovalLocs.push_back(Chunk.Fun.getConstQualifierLoc());          if (Chunk.Fun.TypeQuals & Qualifiers::Volatile)            RemovalLocs.push_back(Chunk.Fun.getVolatileQualifierLoc()); -        // FIXME: We do not track the location of the __restrict qualifier. -        //if (Chunk.Fun.TypeQuals & Qualifiers::Restrict) -        //  RemovalLocs.push_back(Chunk.Fun.getRestrictQualifierLoc()); +        if (Chunk.Fun.TypeQuals & Qualifiers::Restrict) +          RemovalLocs.push_back(Chunk.Fun.getRestrictQualifierLoc());          if (!RemovalLocs.empty()) {            std::sort(RemovalLocs.begin(), RemovalLocs.end(),                      BeforeThanCompare<SourceLocation>(S.getSourceManager())); @@ -3153,12 +3160,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,    }    // Apply any undistributed attributes from the declarator. -  if (!T.isNull()) -    if (AttributeList *attrs = D.getAttributes()) -      processTypeAttrs(state, T, TAL_DeclName, attrs); +  if (AttributeList *attrs = D.getAttributes()) +    processTypeAttrs(state, T, TAL_DeclName, attrs);    // Diagnose any ignored type attributes. -  if (!T.isNull()) state.diagnoseIgnoredTypeAttrs(T); +  state.diagnoseIgnoredTypeAttrs(T);    // C++0x [dcl.constexpr]p9:    //  A constexpr specifier used in an object declaration declares the object @@ -3169,7 +3175,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,    // If there was an ellipsis in the declarator, the declaration declares a    // parameter pack whose type may be a pack expansion type. -  if (D.hasEllipsis() && !T.isNull()) { +  if (D.hasEllipsis()) {      // C++0x [dcl.fct]p13:      //   A declarator-id or abstract-declarator containing an ellipsis shall      //   only be used in a parameter-declaration. Such a parameter-declaration @@ -3234,15 +3240,15 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,      case Declarator::TemplateTypeArgContext:        // FIXME: We may want to allow parameter packs in block-literal contexts        // in the future. -      S.Diag(D.getEllipsisLoc(), diag::err_ellipsis_in_declarator_not_parameter); +      S.Diag(D.getEllipsisLoc(), +             diag::err_ellipsis_in_declarator_not_parameter);        D.setEllipsisLoc(SourceLocation());        break;      }    } -  if (T.isNull()) -    return Context.getNullTypeSourceInfo(); -  else if (D.isInvalidType()) +  assert(!T.isNull() && "T must not be null at the end of this function"); +  if (D.isInvalidType())      return Context.getTrivialTypeSourceInfo(T);    return S.GetTypeSourceInfoForDeclarator(D, T, TInfo); @@ -3261,8 +3267,6 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {    TypeSourceInfo *ReturnTypeInfo = nullptr;    QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo); -  if (T.isNull()) -    return Context.getNullTypeSourceInfo();    if (D.isPrototypeContext() && getLangOpts().ObjCAutoRefCount)      inferARCWriteback(state, T); @@ -3376,8 +3380,6 @@ TypeSourceInfo *Sema::GetTypeForDeclaratorCast(Declarator &D, QualType FromTy) {    TypeSourceInfo *ReturnTypeInfo = nullptr;    QualType declSpecTy = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo); -  if (declSpecTy.isNull()) -    return Context.getNullTypeSourceInfo();    if (getLangOpts().ObjCAutoRefCount) {      Qualifiers::ObjCLifetime ownership = Context.getInnerObjCOwnership(FromTy); @@ -3417,6 +3419,8 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {      return AttributeList::AT_ThisCall;    case AttributedType::attr_pascal:      return AttributeList::AT_Pascal; +  case AttributedType::attr_vectorcall: +    return AttributeList::AT_VectorCall;    case AttributedType::attr_pcs:    case AttributedType::attr_pcs_vfp:      return AttributeList::AT_Pcs; @@ -3717,6 +3721,7 @@ namespace {        case NestedNameSpecifier::Namespace:        case NestedNameSpecifier::NamespaceAlias:        case NestedNameSpecifier::Global: +      case NestedNameSpecifier::Super:          llvm_unreachable("Nested-name-specifier must name a type");        } @@ -3975,6 +3980,8 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,        ASIdx = LangAS::opencl_local; break;      case AttributeList::AT_OpenCLConstantAddressSpace:        ASIdx = LangAS::opencl_constant; break; +    case AttributeList::AT_OpenCLGenericAddressSpace: +      ASIdx = LangAS::opencl_generic; break;      default:        assert(Attr.getKind() == AttributeList::AT_OpenCLPrivateAddressSpace);        ASIdx = 0; break; @@ -4432,6 +4439,8 @@ static AttributedType::Kind getCCTypeAttrKind(AttributeList &Attr) {      return AttributedType::attr_thiscall;    case AttributeList::AT_Pascal:      return AttributedType::attr_pascal; +  case AttributeList::AT_VectorCall: +    return AttributedType::attr_vectorcall;    case AttributeList::AT_Pcs: {      // The attribute may have had a fixit applied where we treated an      // identifier as a string literal.  The contents of the string are valid, @@ -4549,7 +4558,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,    }    // Diagnose use of callee-cleanup calling convention on variadic functions. -  if (isCalleeCleanup(CC)) { +  if (!supportsVariadicCall(CC)) {      const FunctionProtoType *FnP = dyn_cast<FunctionProtoType>(fn);      if (FnP && FnP->isVariadic()) {        unsigned DiagID = diag::err_cconv_varargs; @@ -4564,23 +4573,12 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,      }    } -  // Diagnose the use of X86 fastcall on unprototyped functions. -  if (CC == CC_X86FastCall) { -    if (isa<FunctionNoProtoType>(fn)) { -      S.Diag(attr.getLoc(), diag::err_cconv_knr) -        << FunctionType::getNameForCallConv(CC); -      attr.setInvalid(); -      return true; -    } - -    // Also diagnose fastcall with regparm. -    if (fn->getHasRegParm()) { -      S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible) -        << "regparm" -        << FunctionType::getNameForCallConv(CC); -      attr.setInvalid(); -      return true; -    } +  // Also diagnose fastcall with regparm. +  if (CC == CC_X86FastCall && fn->getHasRegParm()) { +    S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible) +        << "regparm" << FunctionType::getNameForCallConv(CC_X86FastCall); +    attr.setInvalid(); +    return true;    }    // Modify the CC from the wrapped function type, wrap it all back, and then @@ -4739,9 +4737,7 @@ static bool isPermittedNeonBaseType(QualType &Ty,    // Signed poly is mathematically wrong, but has been baked into some ABIs by    // now.    bool IsPolyUnsigned = Triple.getArch() == llvm::Triple::aarch64 || -                        Triple.getArch() == llvm::Triple::aarch64_be || -                        Triple.getArch() == llvm::Triple::arm64 || -                        Triple.getArch() == llvm::Triple::arm64_be; +                        Triple.getArch() == llvm::Triple::aarch64_be;    if (VecKind == VectorType::NeonPolyVector) {      if (IsPolyUnsigned) {        // AArch64 polynomial vectors are unsigned and support poly64. @@ -4759,9 +4755,7 @@ static bool isPermittedNeonBaseType(QualType &Ty,    // Non-polynomial vector types: the usual suspects are allowed, as well as    // float64_t on AArch64.    bool Is64Bit = Triple.getArch() == llvm::Triple::aarch64 || -                 Triple.getArch() == llvm::Triple::aarch64_be || -                 Triple.getArch() == llvm::Triple::arm64 || -                 Triple.getArch() == llvm::Triple::arm64_be; +                 Triple.getArch() == llvm::Triple::aarch64_be;    if (Is64Bit && BTy->getKind() == BuiltinType::Double)      return true; @@ -4899,6 +4893,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,      case AttributeList::AT_OpenCLGlobalAddressSpace:      case AttributeList::AT_OpenCLLocalAddressSpace:      case AttributeList::AT_OpenCLConstantAddressSpace: +    case AttributeList::AT_OpenCLGenericAddressSpace:      case AttributeList::AT_AddressSpace:        HandleAddressSpaceTypeAttribute(type, attr, state.getSema());        attr.setUsedAsTypeAttr(); @@ -5098,31 +5093,9 @@ static bool hasVisibleDefinition(Sema &S, NamedDecl *D, NamedDecl **Suggested) {    // If this definition was instantiated from a template, map back to the    // pattern from which it was instantiated. -  // -  // FIXME: There must be a better place for this to live.    if (auto *RD = dyn_cast<CXXRecordDecl>(D)) { -    if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { -      auto From = TD->getInstantiatedFrom(); -      if (auto *CTD = From.dyn_cast<ClassTemplateDecl*>()) { -        while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) { -          if (NewCTD->isMemberSpecialization()) -            break; -          CTD = NewCTD; -        } -        RD = CTD->getTemplatedDecl(); -      } else if (auto *CTPSD = From.dyn_cast< -                     ClassTemplatePartialSpecializationDecl *>()) { -        while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) { -          if (NewCTPSD->isMemberSpecialization()) -            break; -          CTPSD = NewCTPSD; -        } -        RD = CTPSD; -      } -    } else if (isTemplateInstantiation(RD->getTemplateSpecializationKind())) { -      while (auto *NewRD = RD->getInstantiatedFromMemberClass()) -        RD = NewRD; -    } +    if (auto *Pattern = RD->getTemplateInstantiationPattern()) +      RD = Pattern;      D = RD->getDefinition();    } else if (auto *ED = dyn_cast<EnumDecl>(D)) {      while (auto *NewED = ED->getInstantiatedFromMemberEnum()) @@ -5178,14 +5151,6 @@ static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {              ? S.ImplicitMSInheritanceAttrLoc              : RD->getSourceRange()));    } - -  if (RD->hasDefinition()) { -    // Assign inheritance models to all of the base classes, because now we can -    // form pointers to members of base classes without calling -    // RequireCompleteType on the pointer to member of the base class type. -    for (const CXXBaseSpecifier &BS : RD->bases()) -      assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl()); -  }  }  /// \brief The implementation of RequireCompleteType @@ -5510,6 +5475,8 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) {    } else if (const ObjCPropertyRefExpr *PR = dyn_cast<ObjCPropertyRefExpr>(E)) {      if (PR->isExplicitProperty())        return PR->getExplicitProperty()->getType(); +  } else if (auto *PE = dyn_cast<PredefinedExpr>(E)) { +    return PE->getType();    }    // C++11 [expr.lambda.prim]p18: @@ -5550,11 +5517,19 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) {    return T;  } -QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) { +QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc, +                                 bool AsUnevaluated) {    ExprResult ER = CheckPlaceholderExpr(E);    if (ER.isInvalid()) return QualType();    E = ER.get(); +  if (AsUnevaluated && ActiveTemplateInstantiations.empty() && +      E->HasSideEffects(Context, false)) { +    // The expression operand for decltype is in an unevaluated expression +    // context, so side effects could result in unintended consequences. +    Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context); +  } +    return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));  } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 312811d2c008..36abbb624af7 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -11,8 +11,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H -#define LLVM_CLANG_SEMA_TREETRANSFORM_H +#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H +#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H  #include "TypeLocBuilder.h"  #include "clang/AST/Decl.h" @@ -327,6 +327,27 @@ public:    /// \returns the transformed OpenMP clause.    OMPClause *TransformOMPClause(OMPClause *S); +  /// \brief Transform the given attribute. +  /// +  /// By default, this routine transforms a statement by delegating to the +  /// appropriate TransformXXXAttr function to transform a specific kind +  /// of attribute. Subclasses may override this function to transform +  /// attributed statements using some other mechanism. +  /// +  /// \returns the transformed attribute +  const Attr *TransformAttr(const Attr *S); + +/// \brief Transform the specified attribute. +/// +/// Subclasses should override the transformation of attributes with a pragma +/// spelling to transform expressions stored within the attribute. +/// +/// \returns the transformed attribute. +#define ATTR(X) +#define PRAGMA_SPELLING_ATTR(X)                                                \ +  const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; } +#include "clang/Basic/AttrList.inc" +    /// \brief Transform the given expression.    ///    /// By default, this routine transforms an expression by delegating to the @@ -542,10 +563,17 @@ public:    QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);  #include "clang/AST/TypeLocNodes.def" +  template<typename Fn>    QualType TransformFunctionProtoType(TypeLocBuilder &TLB,                                        FunctionProtoTypeLoc TL,                                        CXXRecordDecl *ThisContext, -                                      unsigned ThisTypeQuals); +                                      unsigned ThisTypeQuals, +                                      Fn TransformExceptionSpec); + +  bool TransformExceptionSpec(SourceLocation Loc, +                              FunctionProtoType::ExceptionSpecInfo &ESI, +                              SmallVectorImpl<QualType> &Exceptions, +                              bool &Changed);    StmtResult TransformSEHHandler(Stmt *Handler); @@ -560,10 +588,9 @@ public:                                                 TemplateName Template,                                                 CXXScopeSpec &SS); -  QualType -  TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, -                                               DependentTemplateSpecializationTypeLoc TL, -                                         NestedNameSpecifierLoc QualifierLoc); +  QualType TransformDependentTemplateSpecializationType( +      TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, +      NestedNameSpecifierLoc QualifierLoc);    /// \brief Transforms the parameters of a function type into the    /// given vectors. @@ -1665,10 +1692,8 @@ public:    }    StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, -                               Stmt *TryBlock, Stmt *Handler, int HandlerIndex, -                               int HandlerParentIndex) { -    return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler, -                                      HandlerIndex, HandlerParentIndex); +                               Stmt *TryBlock, Stmt *Handler) { +    return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);    }    StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, @@ -1680,6 +1705,15 @@ public:      return getSema().ActOnSEHFinallyBlock(Loc, Block);    } +  /// \brief Build a new predefined expression. +  /// +  /// By default, performs semantic analysis to build the new expression. +  /// Subclasses may override this routine to provide different behavior. +  ExprResult RebuildPredefinedExpr(SourceLocation Loc, +                                   PredefinedExpr::IdentType IT) { +    return getSema().BuildPredefinedExpr(Loc, IT); +  } +    /// \brief Build a new expression that references a declaration.    ///    /// By default, performs semantic analysis to build the new expression. @@ -2757,6 +2791,27 @@ public:      return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);    } +  /// \brief Build a new C++1z fold-expression. +  /// +  /// By default, performs semantic analysis in order to build a new fold +  /// expression. +  ExprResult RebuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, +                                BinaryOperatorKind Operator, +                                SourceLocation EllipsisLoc, Expr *RHS, +                                SourceLocation RParenLoc) { +    return getSema().BuildCXXFoldExpr(LParenLoc, LHS, Operator, EllipsisLoc, +                                      RHS, RParenLoc); +  } + +  /// \brief Build an empty C++1z fold-expression with the given operator. +  /// +  /// By default, produces the fallback value for the fold-expression, or +  /// produce an error if there is no fallback value. +  ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, +                                     BinaryOperatorKind Operator) { +    return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator); +  } +    /// \brief Build a new atomic operation expression.    ///    /// By default, performs semantic analysis to build the new expression. @@ -3103,6 +3158,14 @@ TreeTransform<Derived>::TransformNestedNameSpecifierLoc(        SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());        break; +    case NestedNameSpecifier::Super: { +      CXXRecordDecl *RD = +          cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( +              SourceLocation(), QNNS->getAsRecordDecl())); +      SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc()); +      break; +    } +      case NestedNameSpecifier::TypeSpecWithTemplate:      case NestedNameSpecifier::TypeSpec: {        TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType, @@ -4515,15 +4578,20 @@ template<typename Derived>  QualType  TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,                                                     FunctionProtoTypeLoc TL) { -  return getDerived().TransformFunctionProtoType(TLB, TL, nullptr, 0); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, -                                                   FunctionProtoTypeLoc TL, -                                                   CXXRecordDecl *ThisContext, -                                                   unsigned ThisTypeQuals) { +  SmallVector<QualType, 4> ExceptionStorage; +  TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. +  return getDerived().TransformFunctionProtoType( +      TLB, TL, nullptr, 0, +      [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { +        return This->TransformExceptionSpec(TL.getBeginLoc(), ESI, +                                            ExceptionStorage, Changed); +      }); +} + +template<typename Derived> template<typename Fn> +QualType TreeTransform<Derived>::TransformFunctionProtoType( +    TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, +    unsigned ThisTypeQuals, Fn TransformExceptionSpec) {    // Transform the parameters and return type.    //    // We are required to instantiate the params and return type in source order. @@ -4568,15 +4636,21 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,        return QualType();    } -  // FIXME: Need to transform the exception-specification too. +  FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo(); + +  bool EPIChanged = false; +  if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged)) +    return QualType(); + +  // FIXME: Need to transform ConsumedParameters for variadic template +  // expansion.    QualType Result = TL.getType();    if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||        T->getNumParams() != ParamTypes.size() ||        !std::equal(T->param_type_begin(), T->param_type_end(), -                  ParamTypes.begin())) { -    Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, -                                                   T->getExtProtoInfo()); +                  ParamTypes.begin()) || EPIChanged) { +    Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);      if (Result.isNull())        return QualType();    } @@ -4593,6 +4667,107 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,  }  template<typename Derived> +bool TreeTransform<Derived>::TransformExceptionSpec( +    SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI, +    SmallVectorImpl<QualType> &Exceptions, bool &Changed) { +  assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated); + +  // Instantiate a dynamic noexcept expression, if any. +  if (ESI.Type == EST_ComputedNoexcept) { +    EnterExpressionEvaluationContext Unevaluated(getSema(), +                                                 Sema::ConstantEvaluated); +    ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr); +    if (NoexceptExpr.isInvalid()) +      return true; + +    NoexceptExpr = getSema().CheckBooleanCondition( +        NoexceptExpr.get(), NoexceptExpr.get()->getLocStart()); +    if (NoexceptExpr.isInvalid()) +      return true; + +    if (!NoexceptExpr.get()->isValueDependent()) { +      NoexceptExpr = getSema().VerifyIntegerConstantExpression( +          NoexceptExpr.get(), nullptr, +          diag::err_noexcept_needs_constant_expression, +          /*AllowFold*/false); +      if (NoexceptExpr.isInvalid()) +        return true; +    } + +    if (ESI.NoexceptExpr != NoexceptExpr.get()) +      Changed = true; +    ESI.NoexceptExpr = NoexceptExpr.get(); +  } + +  if (ESI.Type != EST_Dynamic) +    return false; + +  // Instantiate a dynamic exception specification's type. +  for (QualType T : ESI.Exceptions) { +    if (const PackExpansionType *PackExpansion = +            T->getAs<PackExpansionType>()) { +      Changed = true; + +      // We have a pack expansion. Instantiate it. +      SmallVector<UnexpandedParameterPack, 2> Unexpanded; +      SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), +                                              Unexpanded); +      assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); + +      // Determine whether the set of unexpanded parameter packs can and +      // should +      // be expanded. +      bool Expand = false; +      bool RetainExpansion = false; +      Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); +      // FIXME: Track the location of the ellipsis (and track source location +      // information for the types in the exception specification in general). +      if (getDerived().TryExpandParameterPacks( +              Loc, SourceRange(), Unexpanded, Expand, +              RetainExpansion, NumExpansions)) +        return true; + +      if (!Expand) { +        // We can't expand this pack expansion into separate arguments yet; +        // just substitute into the pattern and create a new pack expansion +        // type. +        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); +        QualType U = getDerived().TransformType(PackExpansion->getPattern()); +        if (U.isNull()) +          return true; + +        U = SemaRef.Context.getPackExpansionType(U, NumExpansions); +        Exceptions.push_back(U); +        continue; +      } + +      // Substitute into the pack expansion pattern for each slice of the +      // pack. +      for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { +        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx); + +        QualType U = getDerived().TransformType(PackExpansion->getPattern()); +        if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc)) +          return true; + +        Exceptions.push_back(U); +      } +    } else { +      QualType U = getDerived().TransformType(T); +      if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc)) +        return true; +      if (T != U) +        Changed = true; + +      Exceptions.push_back(U); +    } +  } + +  ESI.Exceptions = Exceptions; +  return false; +} + +template<typename Derived>  QualType TreeTransform<Derived>::TransformFunctionNoProtoType(                                                   TypeLocBuilder &TLB,                                                   FunctionNoProtoTypeLoc TL) { @@ -5147,8 +5322,8 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,      if (const TemplateSpecializationType *TST =            NamedT->getAs<TemplateSpecializationType>()) {        TemplateName Template = TST->getTemplateName(); -      if (TypeAliasTemplateDecl *TAT = -          dyn_cast_or_null<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) { +      if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>( +              Template.getAsTemplateDecl())) {          SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),                       diag::err_tag_reference_non_tag) << 4;          SemaRef.Diag(TAT->getLocation(), diag::note_declared_at); @@ -5529,19 +5704,43 @@ TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {                                         SubStmt.get());  } -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) { +template <typename Derived> +const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) { +  if (!R) +    return R; + +  switch (R->getKind()) { +// Transform attributes with a pragma spelling by calling TransformXXXAttr. +#define ATTR(X) +#define PRAGMA_SPELLING_ATTR(X)                                                \ +  case attr::X:                                                                \ +    return getDerived().Transform##X##Attr(cast<X##Attr>(R)); +#include "clang/Basic/AttrList.inc" +  default: +    return R; +  } +} + +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) { +  bool AttrsChanged = false; +  SmallVector<const Attr *, 1> Attrs; + +  // Visit attributes and keep track if any are transformed. +  for (const auto *I : S->getAttrs()) { +    const Attr *R = getDerived().TransformAttr(I); +    AttrsChanged |= (I != R); +    Attrs.push_back(R); +  } +    StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());    if (SubStmt.isInvalid())      return StmtError(); -  // TODO: transform attributes -  if (SubStmt.get() == S->getSubStmt() /* && attrs are the same */) +  if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)      return S; -  return getDerived().RebuildAttributedStmt(S->getAttrLoc(), -                                            S->getAttrs(), +  return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,                                              SubStmt.get());  } @@ -5824,7 +6023,8 @@ TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {  template<typename Derived>  StmtResult  TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) { -  ExprResult Result = getDerived().TransformExpr(S->getRetValue()); +  ExprResult Result = getDerived().TransformInitializer(S->getRetValue(), +                                                        /*NotCopyInit*/false);    if (Result.isInvalid())      return StmtError(); @@ -6380,9 +6580,8 @@ StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {        Handler.get() == S->getHandler())      return S; -  return getDerived().RebuildSEHTryStmt( -      S->getIsCXXTry(), S->getTryLoc(), TryBlock.get(), Handler.get(), -      S->getHandlerIndex(), S->getHandlerParentIndex()); +  return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(), +                                        TryBlock.get(), Handler.get());  }  template <typename Derived> @@ -6504,6 +6703,17 @@ TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {  template <typename Derived>  StmtResult +TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr, +                                             D->getLocStart()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived> +StmtResult  TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {    DeclarationNameInfo DirName;    getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr, @@ -6568,6 +6778,17 @@ StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(  }  template <typename Derived> +StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective( +    OMPParallelForSimdDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName, +                                             nullptr, D->getLocStart()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived>  StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(      OMPParallelSectionsDirective *D) {    DeclarationNameInfo DirName; @@ -6633,6 +6854,50 @@ TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {    return Res;  } +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr, +                                             D->getLocStart()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr, +                                             D->getLocStart()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr, +                                             D->getLocStart()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr, +                                             D->getLocStart()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} +  //===----------------------------------------------------------------------===//  // OpenMP clause transformation  //===----------------------------------------------------------------------===// @@ -6740,6 +7005,39 @@ TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {  }  template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived>  OMPClause *  TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {    llvm::SmallVector<Expr *, 16> Vars; @@ -6912,7 +7210,11 @@ OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {  template<typename Derived>  ExprResult  TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) { -  return E; +  if (!E->isTypeDependent()) +    return E; + +  return getDerived().RebuildPredefinedExpr(E->getLocation(), +                                            E->getIdentType());  }  template<typename Derived> @@ -7161,6 +7463,12 @@ TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {  template<typename Derived>  ExprResult +TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) { +  return E; +} + +template<typename Derived> +ExprResult  TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {    // Rebuild the syntactic form.  The original syntactic form has    // opaque-value expressions in it, so strip those away and rebuild @@ -7873,15 +8181,11 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {        Type == E->getTypeInfoAsWritten() &&        SubExpr.get() == E->getSubExpr())      return E; -  return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(), -                                              E->getStmtClass(), -                                              E->getAngleBrackets().getBegin(), -                                              Type, -                                              E->getAngleBrackets().getEnd(), -                                              // FIXME. this should be '(' location -                                              E->getAngleBrackets().getEnd(), -                                              SubExpr.get(), -                                              E->getRParenLoc()); +  return getDerived().RebuildCXXNamedCastExpr( +      E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(), +      Type, E->getAngleBrackets().getEnd(), +      // FIXME. this should be '(' location +      E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());  }  template<typename Derived> @@ -8786,113 +9090,68 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(  template<typename Derived>  ExprResult  TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { -    -  // Transform any init-capture expressions before entering the scope of the  +  // Transform any init-capture expressions before entering the scope of the    // lambda body, because they are not semantically within that scope.    SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes;    InitCaptureExprsAndTypes.resize(E->explicit_capture_end() -        E->explicit_capture_begin()); -      for (LambdaExpr::capture_iterator C = E->capture_begin(), -      CEnd = E->capture_end(); -      C != CEnd; ++C) { +                                    CEnd = E->capture_end(); +       C != CEnd; ++C) {      if (!C->isInitCapture())        continue; -    EnterExpressionEvaluationContext  EEEC(getSema(),  -        Sema::PotentiallyEvaluated);     +    EnterExpressionEvaluationContext EEEC(getSema(), +                                          Sema::PotentiallyEvaluated);      ExprResult NewExprInitResult = getDerived().TransformInitializer(          C->getCapturedVar()->getInit(),          C->getCapturedVar()->getInitStyle() == VarDecl::CallInit); -     +      if (NewExprInitResult.isInvalid())        return ExprError();      Expr *NewExprInit = NewExprInitResult.get(); -       +      VarDecl *OldVD = C->getCapturedVar(); -    QualType NewInitCaptureType =  -        getSema().performLambdaInitCaptureInitialization(C->getLocation(),  -            OldVD->getType()->isReferenceType(), OldVD->getIdentifier(),  +    QualType NewInitCaptureType = +        getSema().performLambdaInitCaptureInitialization(C->getLocation(), +            OldVD->getType()->isReferenceType(), OldVD->getIdentifier(),              NewExprInit);      NewExprInitResult = NewExprInit;      InitCaptureExprsAndTypes[C - E->capture_begin()] =          std::make_pair(NewExprInitResult, NewInitCaptureType); -    }    LambdaScopeInfo *LSI = getSema().PushLambdaScope(); +  Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); +    // Transform the template parameters, and add them to the current    // instantiation scope. The null case is handled correctly.    LSI->GLTemplateParameterList = getDerived().TransformTemplateParameterList(        E->getTemplateParameterList()); -  // Check to see if the TypeSourceInfo of the call operator needs to -  // be transformed, and if so do the transformation in the  -  // CurrentInstantiationScope. - -  TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); -  FunctionProtoTypeLoc OldCallOpFPTL =  -      OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); +  // Transform the type of the original lambda's call operator. +  // The transformation MUST be done in the CurrentInstantiationScope since +  // it introduces a mapping of the original to the newly created +  // transformed parameters.    TypeSourceInfo *NewCallOpTSI = nullptr; - -  const bool CallOpWasAlreadyTransformed =  -      getDerived().AlreadyTransformed(OldCallOpTSI->getType());  -   -  // Use the Old Call Operator's TypeSourceInfo if it is already transformed. -  if (CallOpWasAlreadyTransformed)   -    NewCallOpTSI = OldCallOpTSI;   -  else { -    // Transform the TypeSourceInfo of the Original Lambda's Call Operator. -    // The transformation MUST be done in the CurrentInstantiationScope since -    // it introduces a mapping of the original to the newly created  -    // transformed parameters. +  { +    TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); +    FunctionProtoTypeLoc OldCallOpFPTL =  +        OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();      TypeLocBuilder NewCallOpTLBuilder; -    QualType NewCallOpType = TransformFunctionProtoType(NewCallOpTLBuilder,  -                                                        OldCallOpFPTL,  -                                                        nullptr, 0); +    SmallVector<QualType, 4> ExceptionStorage; +    TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. +    QualType NewCallOpType = TransformFunctionProtoType( +        NewCallOpTLBuilder, OldCallOpFPTL, nullptr, 0, +        [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { +          return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI, +                                              ExceptionStorage, Changed); +        }); +    if (NewCallOpType.isNull()) +      return ExprError();      NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,                                                          NewCallOpType);    } -  // Extract the ParmVarDecls from the NewCallOpTSI and add them to -  // the vector below - this will be used to synthesize the  -  // NewCallOperator.  Additionally, add the parameters of the untransformed  -  // lambda call operator to the CurrentInstantiationScope. -  SmallVector<ParmVarDecl *, 4> Params;   -  { -    FunctionProtoTypeLoc NewCallOpFPTL =  -        NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>(); -    ParmVarDecl **NewParamDeclArray = NewCallOpFPTL.getParmArray(); -    const unsigned NewNumArgs = NewCallOpFPTL.getNumParams(); - -    for (unsigned I = 0; I < NewNumArgs; ++I) { -      // If this call operator's type does not require transformation,  -      // the parameters do not get added to the current instantiation scope,  -      // - so ADD them! This allows the following to compile when the enclosing -      // template is specialized and the entire lambda expression has to be -      // transformed.  -      // template<class T> void foo(T t) { -      //   auto L = [](auto a) { -      //       auto M = [](char b) { <-- note: non-generic lambda -      //         auto N = [](auto c) { -      //            int x = sizeof(a); -      //            x = sizeof(b); <-- specifically this line -      //            x = sizeof(c); -      //          }; -      //        }; -      //      }; -      //    } -      // foo('a') -      if (CallOpWasAlreadyTransformed) -        getDerived().transformedLocalDecl(NewParamDeclArray[I], -                                          NewParamDeclArray[I]); -      // Add to Params array, so these parameters can be used to create -      // the newly transformed call operator. -      Params.push_back(NewParamDeclArray[I]); -    } -  } - -  if (!NewCallOpTSI) -    return ExprError();    // Create the local class that will describe the lambda.    CXXRecordDecl *Class @@ -8900,19 +9159,21 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {                                          NewCallOpTSI,                                          /*KnownDependent=*/false,                                          E->getCaptureDefault()); -    getDerived().transformedLocalDecl(E->getLambdaClass(), Class);    // Build the call operator. -  CXXMethodDecl *NewCallOperator -    = getSema().startLambdaDefinition(Class, E->getIntroducerRange(), -                                      NewCallOpTSI, -                                      E->getCallOperator()->getLocEnd(), -                                      Params); +  CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition( +      Class, E->getIntroducerRange(), NewCallOpTSI, +      E->getCallOperator()->getLocEnd(), +      NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams());    LSI->CallOperator = NewCallOperator;    getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); +  // TransformLambdaScope will manage the function scope, so we can disable the +  // cleanup. +  FuncScopeCleanup.disable(); +    return getDerived().TransformLambdaScope(E, NewCallOperator,         InitCaptureExprsAndTypes);  } @@ -8954,6 +9215,10 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,        getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit());        continue;      } +    // Captured expression will be recaptured during captured variables +    // rebuilding. +    if (C->capturesVLAType()) +      continue;      // Rebuild init-captures, including the implied field declaration.      if (C->isInitCapture()) { @@ -9033,7 +9298,7 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,      VarDecl *CapturedVar        = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),                                                           C->getCapturedVar())); -    if (!CapturedVar) { +    if (!CapturedVar || CapturedVar->isInvalidDecl()) {        Invalid = true;        continue;      } @@ -9398,6 +9663,128 @@ TreeTransform<Derived>::TransformMaterializeTemporaryExpr(  template<typename Derived>  ExprResult +TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) { +  Expr *Pattern = E->getPattern(); + +  SmallVector<UnexpandedParameterPack, 2> Unexpanded; +  getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); +  assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); + +  // Determine whether the set of unexpanded parameter packs can and should +  // be expanded. +  bool Expand = true; +  bool RetainExpansion = false; +  Optional<unsigned> NumExpansions; +  if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(), +                                           Pattern->getSourceRange(), +                                           Unexpanded, +                                           Expand, RetainExpansion, +                                           NumExpansions)) +    return true; + +  if (!Expand) { +    // Do not expand any packs here, just transform and rebuild a fold +    // expression. +    Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); + +    ExprResult LHS = +        E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult(); +    if (LHS.isInvalid()) +      return true; + +    ExprResult RHS = +        E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult(); +    if (RHS.isInvalid()) +      return true; + +    if (!getDerived().AlwaysRebuild() && +        LHS.get() == E->getLHS() && RHS.get() == E->getRHS()) +      return E; + +    return getDerived().RebuildCXXFoldExpr( +        E->getLocStart(), LHS.get(), E->getOperator(), E->getEllipsisLoc(), +        RHS.get(), E->getLocEnd()); +  } + +  // The transform has determined that we should perform an elementwise +  // expansion of the pattern. Do so. +  ExprResult Result = getDerived().TransformExpr(E->getInit()); +  if (Result.isInvalid()) +    return true; +  bool LeftFold = E->isLeftFold(); + +  // If we're retaining an expansion for a right fold, it is the innermost +  // component and takes the init (if any). +  if (!LeftFold && RetainExpansion) { +    ForgetPartiallySubstitutedPackRAII Forget(getDerived()); + +    ExprResult Out = getDerived().TransformExpr(Pattern); +    if (Out.isInvalid()) +      return true; + +    Result = getDerived().RebuildCXXFoldExpr( +        E->getLocStart(), Out.get(), E->getOperator(), E->getEllipsisLoc(), +        Result.get(), E->getLocEnd()); +    if (Result.isInvalid()) +      return true; +  } + +  for (unsigned I = 0; I != *NumExpansions; ++I) { +    Sema::ArgumentPackSubstitutionIndexRAII SubstIndex( +        getSema(), LeftFold ? I : *NumExpansions - I - 1); +    ExprResult Out = getDerived().TransformExpr(Pattern); +    if (Out.isInvalid()) +      return true; + +    if (Out.get()->containsUnexpandedParameterPack()) { +      // We still have a pack; retain a pack expansion for this slice. +      Result = getDerived().RebuildCXXFoldExpr( +          E->getLocStart(), +          LeftFold ? Result.get() : Out.get(), +          E->getOperator(), E->getEllipsisLoc(), +          LeftFold ? Out.get() : Result.get(), +          E->getLocEnd()); +    } else if (Result.isUsable()) { +      // We've got down to a single element; build a binary operator. +      Result = getDerived().RebuildBinaryOperator( +          E->getEllipsisLoc(), E->getOperator(), +          LeftFold ? Result.get() : Out.get(), +          LeftFold ? Out.get() : Result.get()); +    } else +      Result = Out; + +    if (Result.isInvalid()) +      return true; +  } + +  // If we're retaining an expansion for a left fold, it is the outermost +  // component and takes the complete expansion so far as its init (if any). +  if (LeftFold && RetainExpansion) { +    ForgetPartiallySubstitutedPackRAII Forget(getDerived()); + +    ExprResult Out = getDerived().TransformExpr(Pattern); +    if (Out.isInvalid()) +      return true; + +    Result = getDerived().RebuildCXXFoldExpr( +        E->getLocStart(), Result.get(), +        E->getOperator(), E->getEllipsisLoc(), +        Out.get(), E->getLocEnd()); +    if (Result.isInvalid()) +      return true; +  } + +  // If we had no init and an empty pack, and we're not retaining an expansion, +  // then produce a fallback value or error. +  if (Result.isUnset()) +    return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(), +                                                E->getOperator()); + +  return Result; +} + +template<typename Derived> +ExprResult  TreeTransform<Derived>::TransformCXXStdInitializerListExpr(      CXXStdInitializerListExpr *E) {    return getDerived().TransformExpr(E->getSubExpr()); @@ -10292,7 +10679,7 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,      SourceLocation RBrace;      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) { -        DeclarationNameLoc &NameLoc = DRE->getNameInfo().getInfo(); +        DeclarationNameLoc NameLoc = DRE->getNameInfo().getInfo();          LBrace = SourceLocation::getFromRawEncoding(                      NameLoc.CXXOperatorName.BeginOpNameLoc);          RBrace = SourceLocation::getFromRawEncoding( @@ -10348,9 +10735,16 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,    // The scope type is now known to be a valid nested name specifier    // component. Tack it on to the end of the nested name specifier. -  if (ScopeType) -    SS.Extend(SemaRef.Context, SourceLocation(), -              ScopeType->getTypeLoc(), CCLoc); +  if (ScopeType) { +    if (!ScopeType->getType()->getAs<TagType>()) { +      getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(), +                     diag::err_expected_class_or_namespace) +          << ScopeType->getType() << getSema().getLangOpts().CPlusPlus; +      return ExprError(); +    } +    SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(), +              CCLoc); +  }    SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.    return getSema().BuildMemberReferenceExpr(Base, BaseType, @@ -10397,4 +10791,4 @@ TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {  } // end namespace clang -#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H +#endif diff --git a/lib/Sema/TypeLocBuilder.h b/lib/Sema/TypeLocBuilder.h index c3f874e1a854..82844b391467 100644 --- a/lib/Sema/TypeLocBuilder.h +++ b/lib/Sema/TypeLocBuilder.h @@ -12,8 +12,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_TYPELOCBUILDER_H -#define LLVM_CLANG_SEMA_TYPELOCBUILDER_H +#ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H +#define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H  #include "clang/AST/ASTContext.h"  #include "clang/AST/TypeLoc.h"  | 
