[llvm-branch-commits] [clang] af0dbaa - Revert "Following up on PR48517, fix handling of template arguments that refer"

Arthur Eubanks via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 22 10:27:44 PST 2020


Author: Arthur Eubanks
Date: 2020-12-22T10:18:08-08:00
New Revision: af0dbaaa38f54b0366177aae43545a8848d3fe56

URL: https://github.com/llvm/llvm-project/commit/af0dbaaa38f54b0366177aae43545a8848d3fe56
DIFF: https://github.com/llvm/llvm-project/commit/af0dbaaa38f54b0366177aae43545a8848d3fe56.diff

LOG: Revert "Following up on PR48517, fix handling of template arguments that refer"

This reverts commit 8c1f2d15b826591cdf6bd6b468b8a7d23377b29e.

This is part of 5 commits being reverted due to https://crbug.com/1161059. See bug for repro.

Added: 
    clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Modified: 
    clang/include/clang/AST/Expr.h
    clang/include/clang/AST/TemplateBase.h
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/ComputeDependence.cpp
    clang/lib/AST/Expr.cpp
    clang/lib/AST/ExprCXX.cpp
    clang/lib/AST/ExprConstant.cpp
    clang/lib/AST/TemplateBase.cpp
    clang/lib/Sema/SemaOverload.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/test/OpenMP/distribute_dist_schedule_messages.cpp
    clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
    clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
    clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
    clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
    clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
    clang/test/OpenMP/target_simd_collapse_messages.cpp
    clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
    clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
    clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
    clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
    clang/test/OpenMP/target_update_from_messages.cpp
    clang/test/OpenMP/target_update_to_messages.cpp
    clang/test/OpenMP/task_messages.cpp
    clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
    clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
    clang/test/SemaCXX/warn-unused-lambda-capture.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp

Removed: 
    clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp


################################################################################
diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index e1c3b6944142..c8d87ec48a3f 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -578,12 +578,12 @@ class Expr : public ValueStmt {
   struct EvalStatus {
     /// Whether the evaluated expression has side effects.
     /// For example, (f() && 0) can be folded, but it still has side effects.
-    bool HasSideEffects = false;
+    bool HasSideEffects;
 
     /// Whether the evaluation hit undefined behavior.
     /// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
     /// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
-    bool HasUndefinedBehavior = false;
+    bool HasUndefinedBehavior;
 
     /// Diag - If this is non-null, it will be filled in with a stack of notes
     /// indicating why evaluation failed (or why it failed to produce a constant
@@ -592,7 +592,10 @@ class Expr : public ValueStmt {
     /// foldable. If the expression is foldable, but not a constant expression,
     /// the notes will describes why it isn't a constant expression. If the
     /// expression *is* a constant expression, no notes will be produced.
-    SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
+    SmallVectorImpl<PartialDiagnosticAt> *Diag;
+
+    EvalStatus()
+        : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
 
     // hasSideEffects - Return true if the evaluated expression has
     // side effects.
@@ -603,11 +606,8 @@ class Expr : public ValueStmt {
 
   /// EvalResult is a struct with detailed info about an evaluated expression.
   struct EvalResult : EvalStatus {
-    /// This is the value the expression can be folded to.
+    /// Val - This is the value the expression can be folded to.
     APValue Val;
-    /// Indicates whether Val contains a pointer or reference or pointer to
-    /// member naming a templated entity, and thus the value is dependent.
-    bool Dependent = false;
 
     // isGlobalLValue - Return true if the evaluated lvalue expression
     // is global.

diff  --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index abf873a7ee40..7967f8a91214 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -252,12 +252,6 @@ class TemplateArgument {
   /// Whether this template argument is dependent on a template
   /// parameter such that its result can change from one instantiation to
   /// another.
-  ///
-  /// It's not always meaningful to ask whether a template argument is
-  /// dependent before it's been converted to match a template parameter;
-  /// whether a non-type template argument is dependent depends on the
-  /// corresponding parameter. For an unconverted template argument, this
-  /// returns true if the argument *might* be dependent.
   bool isDependent() const;
 
   /// Whether this template argument is dependent on a template
@@ -680,6 +674,13 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
   void initializeFrom(SourceLocation TemplateKWLoc,
                       const TemplateArgumentListInfo &List,
                       TemplateArgumentLoc *OutArgArray);
+  // FIXME: The parameter Deps is the result populated by this method, the
+  // caller doesn't need it since it is populated by computeDependence. remove
+  // it.
+  void initializeFrom(SourceLocation TemplateKWLoc,
+                      const TemplateArgumentListInfo &List,
+                      TemplateArgumentLoc *OutArgArray,
+                      TemplateArgumentDependence &Deps);
   void initializeFrom(SourceLocation TemplateKWLoc);
 
   void copyInto(const TemplateArgumentLoc *ArgArray,

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 2c781eb88415..6b81494e8eff 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3353,8 +3353,7 @@ class Sema final {
                                               llvm::APSInt &Value, CCEKind CCE);
   ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
                                               APValue &Value, CCEKind CCE,
-                                              NamedDecl *Dest = nullptr,
-                                              bool *ValueDependent = nullptr);
+                                              NamedDecl *Dest = nullptr);
 
   /// Abstract base class used to perform a contextual implicit
   /// conversion from an expression to any type passing a filter.

diff  --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index 5262e3cbe233..4026fdc76fd6 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -64,7 +64,7 @@ ExprDependence clang::computeDependence(UnaryOperator *E,
       if (VD && VD->isTemplated()) {
         auto *VarD = dyn_cast<VarDecl>(VD);
         if (!VarD || !VarD->hasLocalStorage())
-          Dep |= ExprDependence::ValueInstantiation;
+          Dep |= ExprDependence::Value;
       }
     }
   }
@@ -443,21 +443,12 @@ ExprDependence clang::computeDependence(DeclRefExpr *E, const ASTContext &Ctx) {
   if (auto *FirstArg = E->getTemplateArgs()) {
     unsigned NumArgs = E->getNumTemplateArgs();
     for (auto *Arg = FirstArg, *End = FirstArg + NumArgs; Arg < End; ++Arg)
-      Deps |= toExprDependence(Arg->getArgument().getDependence() &
-                               ~TemplateArgumentDependence::Dependent);
+      Deps |= toExprDependence(Arg->getArgument().getDependence());
   }
 
   auto *Decl = E->getDecl();
-  auto *Found = E->getFoundDecl();
   auto Type = E->getType();
 
-  // FIXME: For a ParmVarDecl referenced in a function signature, we don't know
-  // its dependence yet!
-  if (!isa<ParmVarDecl>(Decl)) {
-    if (Decl->getDeclContext()->isDependentContext() ||
-        (Found && Found->getDeclContext()->isDependentContext()))
-      Deps |= ExprDependence::Instantiation;
-  }
   if (Decl->isParameterPack())
     Deps |= ExprDependence::UnexpandedPack;
   Deps |= toExprDependence(Type->getDependence()) & ExprDependence::Error;

diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index dafa7136ecb4..a274bf37a407 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -416,9 +416,12 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
       RefersToEnclosingVariableOrCapture;
   DeclRefExprBits.NonOdrUseReason = NOUR;
   if (TemplateArgs) {
+    auto Deps = TemplateArgumentDependence::None;
     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
-        TemplateKWLoc, *TemplateArgs,
-        getTrailingObjects<TemplateArgumentLoc>());
+        TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
+        Deps);
+    assert(!(Deps & TemplateArgumentDependence::Dependent) &&
+           "built a DeclRefExpr with dependent template args");
   } else if (TemplateKWLoc.isValid()) {
     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc);
@@ -1521,8 +1524,16 @@ MemberExpr *MemberExpr::Create(
   MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
                                        NameInfo, T, VK, OK, NOUR);
 
-  // FIXME: Move this into the constructor.
+  // FIXME: remove remaining dependence computation to computeDependence().
+  auto Deps = E->getDependence();
   if (HasQualOrFound) {
+    // FIXME: Wrong. We should be looking at the member declaration we found.
+    if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent())
+      Deps |= ExprDependence::TypeValueInstantiation;
+    else if (QualifierLoc &&
+             QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
+      Deps |= ExprDependence::Instantiation;
+
     E->MemberExprBits.HasQualifierOrFoundDecl = true;
 
     MemberExprNameQualifier *NQ =
@@ -1535,26 +1546,16 @@ MemberExpr *MemberExpr::Create(
       TemplateArgs || TemplateKWLoc.isValid();
 
   if (TemplateArgs) {
+    auto TemplateArgDeps = TemplateArgumentDependence::None;
     E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc, *TemplateArgs,
-        E->getTrailingObjects<TemplateArgumentLoc>());
+        E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps);
+    if (TemplateArgDeps & TemplateArgumentDependence::Instantiation)
+      Deps |= ExprDependence::Instantiation;
   } else if (TemplateKWLoc.isValid()) {
     E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc);
   }
-
-  // FIXME: remove remaining dependence computation to computeDependence().
-  auto Deps = E->getDependence();
-  if (NestedNameSpecifier *Qual = E->getQualifier()) {
-    // FIXME: Wrong. We should be looking at the member declaration we found.
-    if (Qual->isDependent())
-      Deps |= ExprDependence::TypeValueInstantiation;
-    else if (Qual->isInstantiationDependent())
-      Deps |= ExprDependence::Instantiation;
-  }
-  if (TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
-          E->template_arguments()))
-    Deps |= ExprDependence::Instantiation;
   E->setDependence(Deps);
 
   return E;

diff  --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index e1f658923519..8dc9d4296e14 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -433,8 +433,9 @@ OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
   }
 
   if (TemplateArgs) {
+    auto Deps = TemplateArgumentDependence::None;
     getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(
-        TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc());
+        TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), Deps);
   } else if (TemplateKWLoc.isValid()) {
     getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
   }
@@ -463,8 +464,9 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(
   DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
       (Args != nullptr) || TemplateKWLoc.isValid();
   if (Args) {
+    auto Deps = TemplateArgumentDependence::None;
     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
-        TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>());
+        TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>(), Deps);
   } else if (TemplateKWLoc.isValid()) {
     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc);
@@ -1374,9 +1376,10 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
   CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
 
   if (TemplateArgs) {
+    auto Deps = TemplateArgumentDependence::None;
     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
-        TemplateKWLoc, *TemplateArgs,
-        getTrailingObjects<TemplateArgumentLoc>());
+        TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
+        Deps);
   } else if (TemplateKWLoc.isValid()) {
     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc);

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 231a8c3bc8bd..56181bbe1166 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1819,8 +1819,7 @@ static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
 static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
 static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
                            EvalInfo &Info);
-static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
-                             bool &Dependent);
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
 
 /// Evaluate an integer or fixed point expression into an APResult.
 static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
@@ -2108,8 +2107,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
                                   QualType Type, const APValue &Value,
                                   ConstantExprKind Kind,
                                   SourceLocation SubobjectLoc,
-                                  CheckedTemporaries &CheckedTemps,
-                                  bool &Dependent);
+                                  CheckedTemporaries &CheckedTemps);
 
 /// Check that this reference or pointer core constant expression is a valid
 /// value for an address or reference constant expression. Return true if we
@@ -2117,8 +2115,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
 static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
                                           QualType Type, const LValue &LVal,
                                           ConstantExprKind Kind,
-                                          CheckedTemporaries &CheckedTemps,
-                                          bool &Dependent) {
+                                          CheckedTemporaries &CheckedTemps) {
   bool IsReferenceType = Type->isReferenceType();
 
   APValue::LValueBase Base = LVal.getLValueBase();
@@ -2203,8 +2200,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
   }
 
   if (BaseVD) {
-    Dependent |= BaseVD->isTemplated();
-
     if (const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
       // Check if this is a thread-local variable.
       if (Var->getTLSKind())
@@ -2235,9 +2230,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
     }
   } else if (const auto *MTE =
                  dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
-    if (auto *Extending = MTE->getExtendingDecl())
-      Dependent |= Extending->isTemplated();
-
     if (CheckedTemps.insert(MTE).second) {
       QualType TempType = getType(Base);
       if (TempType.isDestructedType()) {
@@ -2250,8 +2242,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
       APValue *V = MTE->getOrCreateValue(false);
       assert(V && "evasluation result refers to uninitialised temporary");
       if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
-                                 Info, MTE->getExprLoc(), TempType, *V, Kind,
-                                 SourceLocation(), CheckedTemps, Dependent))
+                                 Info, MTE->getExprLoc(), TempType, *V,
+                                 Kind, SourceLocation(), CheckedTemps))
         return false;
     }
   }
@@ -2280,15 +2272,13 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
 
 /// Member pointers are constant expressions unless they point to a
 /// non-virtual dllimport member function.
-static bool
-CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc,
-                                     QualType Type, const APValue &Value,
-                                     ConstantExprKind Kind, bool &Dependent) {
+static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
+                                                 SourceLocation Loc,
+                                                 QualType Type,
+                                                 const APValue &Value,
+                                                 ConstantExprKind Kind) {
   const ValueDecl *Member = Value.getMemberPointerDecl();
-  if (!Member)
-    return true;
-  Dependent |= Member->isTemplated();
-  const auto *FD = dyn_cast<CXXMethodDecl>(Member);
+  const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
   if (!FD)
     return true;
   if (FD->isConsteval()) {
@@ -2337,8 +2327,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
                                   QualType Type, const APValue &Value,
                                   ConstantExprKind Kind,
                                   SourceLocation SubobjectLoc,
-                                  CheckedTemporaries &CheckedTemps,
-                                  bool &Dependent) {
+                                  CheckedTemporaries &CheckedTemps) {
   if (!Value.hasValue()) {
     Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
       << true << Type;
@@ -2360,20 +2349,20 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
     for (unsigned I = 0, N = Value.getArrayInitializedElts(); I != N; ++I) {
       if (!CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
                                  Value.getArrayInitializedElt(I), Kind,
-                                 SubobjectLoc, CheckedTemps, Dependent))
+                                 SubobjectLoc, CheckedTemps))
         return false;
     }
     if (!Value.hasArrayFiller())
       return true;
     return CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
                                  Value.getArrayFiller(), Kind, SubobjectLoc,
-                                 CheckedTemps, Dependent);
+                                 CheckedTemps);
   }
   if (Value.isUnion() && Value.getUnionField()) {
     return CheckEvaluationResult(
         CERK, Info, DiagLoc, Value.getUnionField()->getType(),
         Value.getUnionValue(), Kind, Value.getUnionField()->getLocation(),
-        CheckedTemps, Dependent);
+        CheckedTemps);
   }
   if (Value.isStruct()) {
     RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
@@ -2382,7 +2371,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
       for (const CXXBaseSpecifier &BS : CD->bases()) {
         if (!CheckEvaluationResult(CERK, Info, DiagLoc, BS.getType(),
                                    Value.getStructBase(BaseIndex), Kind,
-                                   BS.getBeginLoc(), CheckedTemps, Dependent))
+                                   BS.getBeginLoc(), CheckedTemps))
           return false;
         ++BaseIndex;
       }
@@ -2392,8 +2381,8 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
         continue;
 
       if (!CheckEvaluationResult(CERK, Info, DiagLoc, I->getType(),
-                                 Value.getStructField(I->getFieldIndex()), Kind,
-                                 I->getLocation(), CheckedTemps, Dependent))
+                                 Value.getStructField(I->getFieldIndex()),
+                                 Kind, I->getLocation(), CheckedTemps))
         return false;
     }
   }
@@ -2403,13 +2392,12 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
     LValue LVal;
     LVal.setFrom(Info.Ctx, Value);
     return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal, Kind,
-                                         CheckedTemps, Dependent);
+                                         CheckedTemps);
   }
 
   if (Value.isMemberPointer() &&
       CERK == CheckEvaluationResultKind::ConstantExpression)
-    return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value,
-                                                Kind, Dependent);
+    return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value, Kind);
 
   // Everything else is fine.
   return true;
@@ -2420,7 +2408,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
 /// check that the expression is of literal type.
 static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
                                     QualType Type, const APValue &Value,
-                                    ConstantExprKind Kind, bool &Dependent) {
+                                    ConstantExprKind Kind) {
   // Nothing to check for a constant expression of type 'cv void'.
   if (Type->isVoidType())
     return true;
@@ -2428,18 +2416,17 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
   CheckedTemporaries CheckedTemps;
   return CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
                                Info, DiagLoc, Type, Value, Kind,
-                               SourceLocation(), CheckedTemps, Dependent);
+                               SourceLocation(), CheckedTemps);
 }
 
 /// Check that this evaluated value is fully-initialized and can be loaded by
 /// an lvalue-to-rvalue conversion.
 static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc,
                                   QualType Type, const APValue &Value) {
-  bool Dependent = false;
   CheckedTemporaries CheckedTemps;
   return CheckEvaluationResult(
       CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc, Type, Value,
-      ConstantExprKind::Normal, SourceLocation(), CheckedTemps, Dependent);
+      ConstantExprKind::Normal, SourceLocation(), CheckedTemps);
 }
 
 /// Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless
@@ -11111,9 +11098,7 @@ static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) {
       ArgType->isAnyComplexType() || ArgType->isPointerType() ||
       ArgType->isNullPtrType()) {
     APValue V;
-    bool Dependent = false;
-    if (!::EvaluateAsRValue(Info, Arg, V, Dependent) ||
-        Info.EvalStatus.HasSideEffects) {
+    if (!::EvaluateAsRValue(Info, Arg, V) || Info.EvalStatus.HasSideEffects) {
       Fold.keepDiagnostics();
       return false;
     }
@@ -11415,8 +11400,7 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
       // It's possible for us to be given GLValues if we're called via
       // Expr::tryEvaluateObjectSize.
       APValue RVal;
-      bool Dependent = false;
-      if (!EvaluateAsRValue(Info, E, RVal, Dependent))
+      if (!EvaluateAsRValue(Info, E, RVal))
         return false;
       LVal.setFrom(Info.Ctx, RVal);
     } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
@@ -12845,9 +12829,8 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) {
     LV.set(VD);
     if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
       return false;
-    bool Dependent = false;
     return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
-                                   ConstantExprKind::Normal, Dependent);
+                                   ConstantExprKind::Normal);
   };
   return EvaluateComparisonBinaryOperator(Info, E, OnSuccess, [&]() {
     return ExprEvaluatorBaseTy::VisitBinCmp(E);
@@ -14611,8 +14594,7 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
 
 /// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
 /// lvalue-to-rvalue cast if it is an lvalue.
-static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
-                             bool &Dependent) {
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
   assert(!E->isValueDependent());
   if (Info.EnableNewConstInterp) {
     if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
@@ -14637,7 +14619,7 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
 
   // Check this core constant expression is a constant expression.
   return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
-                                 ConstantExprKind::Normal, Dependent) &&
+                                 ConstantExprKind::Normal) &&
          CheckMemoryLeaks(Info);
 }
 
@@ -14683,7 +14665,7 @@ static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result,
   if (FastEvaluateAsRValue(E, Result, Ctx, IsConst))
     return IsConst;
 
-  return EvaluateAsRValue(Info, E, Result.Val, Result.Dependent);
+  return EvaluateAsRValue(Info, E, Result.Val);
 }
 
 static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
@@ -14793,9 +14775,9 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
   CheckedTemporaries CheckedTemps;
   if (!EvaluateLValue(this, LV, Info) || !Info.discardCleanups() ||
       Result.HasSideEffects ||
-      !CheckLValueConstantExpression(
-          Info, getExprLoc(), Ctx.getLValueReferenceType(getType()), LV,
-          ConstantExprKind::Normal, CheckedTemps, Result.Dependent))
+      !CheckLValueConstantExpression(Info, getExprLoc(),
+                                     Ctx.getLValueReferenceType(getType()), LV,
+                                     ConstantExprKind::Normal, CheckedTemps))
     return false;
 
   LV.moveInto(Result.Val);
@@ -14854,7 +14836,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
     llvm_unreachable("Unhandled cleanup; missing full expression marker?");
 
   if (!CheckConstantExpression(Info, getExprLoc(), getStorageType(Ctx, this),
-                               Result.Val, Kind, Result.Dependent))
+                               Result.Val, Kind))
     return false;
   if (!CheckMemoryLeaks(Info))
     return false;
@@ -14918,9 +14900,8 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
     if (!Info.discardCleanups())
       llvm_unreachable("Unhandled cleanup; missing full expression marker?");
   }
-  bool Dependent = false;
   return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
-                                 ConstantExprKind::Normal, Dependent) &&
+                                 ConstantExprKind::Normal) &&
          CheckMemoryLeaks(Info);
 }
 
@@ -14987,7 +14968,7 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
   Info.InConstantContext = true;
   Info.CheckingForUndefinedBehavior = true;
 
-  bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
+  bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val);
   (void)Result;
   assert(Result && "Could not evaluate expression");
   assert(EVResult.Val.isInt() && "Expression did not evaluate to integer");
@@ -14999,10 +14980,13 @@ void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
   assert(!isValueDependent() &&
          "Expression evaluator can't be called on a dependent expression.");
 
+  bool IsConst;
   EvalResult EVResult;
-  EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
-  Info.CheckingForUndefinedBehavior = true;
-  (void)::EvaluateAsRValue(this, EVResult, Ctx, Info);
+  if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
+    EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+    Info.CheckingForUndefinedBehavior = true;
+    (void)::EvaluateAsRValue(Info, this, EVResult.Val);
+  }
 }
 
 bool Expr::EvalResult::isGlobalLValue() const {
@@ -15552,9 +15536,8 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
   EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
 
   APValue Scratch;
-  bool Dependent = false;
   bool IsConstExpr =
-      ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch, Dependent) &&
+      ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch) &&
       // FIXME: We don't produce a diagnostic for this, but the callers that
       // call us on arbitrary full-expressions should generally not care.
       Info.discardCleanups() && !Status.HasSideEffects;

diff  --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index 44d52c56ffbb..b6af655deff0 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -131,17 +131,25 @@ TemplateArgumentDependence TemplateArgument::getDependence() const {
     return TemplateArgumentDependence::Dependent |
            TemplateArgumentDependence::Instantiation;
 
+  case Declaration: {
+    auto *DC = dyn_cast<DeclContext>(getAsDecl());
+    if (!DC)
+      DC = getAsDecl()->getDeclContext();
+    if (DC->isDependentContext())
+      Deps = TemplateArgumentDependence::Dependent |
+             TemplateArgumentDependence::Instantiation;
+    return Deps;
+  }
+
   case NullPtr:
   case Integral:
-  case Declaration:
     return TemplateArgumentDependence::None;
 
   case Expression:
     Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
-    // Instantiation-dependent expression arguments are considered dependent
-    // until they're resolved to another form.
-    if (Deps & TemplateArgumentDependence::Instantiation)
-      Deps |= TemplateArgumentDependence::Dependent;
+    if (isa<PackExpansionExpr>(getAsExpr()))
+      Deps |= TemplateArgumentDependence::Dependent |
+              TemplateArgumentDependence::Instantiation;
     return Deps;
 
   case Pack:
@@ -536,8 +544,8 @@ ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
   NumTemplateArgs = Info.size();
 
   TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
-  std::uninitialized_copy(Info.arguments().begin(), Info.arguments().end(),
-                          ArgBuffer);
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
 }
 
 void ASTTemplateKWAndArgsInfo::initializeFrom(
@@ -547,8 +555,9 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(
   LAngleLoc = Info.getLAngleLoc();
   RAngleLoc = Info.getRAngleLoc();
   NumTemplateArgs = Info.size();
-  std::uninitialized_copy(Info.arguments().begin(), Info.arguments().end(),
-                          OutArgArray);
+
+  for (unsigned i = 0; i != NumTemplateArgs; ++i)
+    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
 }
 
 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
@@ -559,6 +568,21 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
   NumTemplateArgs = 0;
 }
 
+void ASTTemplateKWAndArgsInfo::initializeFrom(
+    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
+    TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
+  this->TemplateKWLoc = TemplateKWLoc;
+  LAngleLoc = Info.getLAngleLoc();
+  RAngleLoc = Info.getRAngleLoc();
+  NumTemplateArgs = Info.size();
+
+  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
+    Deps |= Info[i].getArgument().getDependence();
+
+    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
+  }
+}
+
 void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
                                         TemplateArgumentListInfo &Info) const {
   Info.setLAngleLoc(LAngleLoc);

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index ac52612ea3b0..13d2125d1a28 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5619,8 +5619,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
                                                    QualType T, APValue &Value,
                                                    Sema::CCEKind CCE,
                                                    bool RequireInt,
-                                                   NamedDecl *Dest,
-                                                   bool *ValueDependent) {
+                                                   NamedDecl *Dest) {
   assert(S.getLangOpts().CPlusPlus11 &&
          "converted constant expression outside C++11");
 
@@ -5744,8 +5743,6 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
 
   if (Result.get()->isValueDependent()) {
     Value = APValue();
-    if (ValueDependent)
-      *ValueDependent = true;
     return Result;
   }
 
@@ -5769,8 +5766,6 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
     Result = ExprError();
   } else {
     Value = Eval.Val;
-    if (ValueDependent)
-      *ValueDependent = Eval.Dependent;
 
     if (Notes.empty()) {
       // It's a constant expression.
@@ -5801,10 +5796,9 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
 
 ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
                                                   APValue &Value, CCEKind CCE,
-                                                  NamedDecl *Dest,
-                                                  bool *ValueDependent) {
+                                                  NamedDecl *Dest) {
   return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false,
-                                            Dest, ValueDependent);
+                                            Dest);
 }
 
 ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
@@ -5814,8 +5808,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
 
   APValue V;
   auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true,
-                                              /*Dest=*/nullptr,
-                                              /*ValueDependent=*/nullptr);
+                                              /*Dest=*/nullptr);
   if (!R.isInvalid() && !R.get()->isValueDependent())
     Value = V.getInt();
   return R;

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7ebd9be831ad..64259767d98a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -6620,12 +6620,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
                                                      Arg, ArgType))
     return true;
 
-  // Don't build a resolved template argument naming a dependent declaration.
-  if (Entity->isTemplated()) {
-    Converted = TemplateArgument(ArgIn);
-    return false;
-  }
-
   // Create the template argument.
   Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()),
                                S.Context.getCanonicalType(ParamType));
@@ -6640,6 +6634,8 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
                                                  QualType ParamType,
                                                  Expr *&ResultArg,
                                                  TemplateArgument &Converted) {
+  bool Invalid = false;
+
   Expr *Arg = ResultArg;
   bool ObjCLifetimeConversion;
 
@@ -6655,7 +6651,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
   // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
   bool ExtraParens = false;
   while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
-    if (!ExtraParens) {
+    if (!Invalid && !ExtraParens) {
       S.Diag(Arg->getBeginLoc(),
              S.getLangOpts().CPlusPlus11
                  ? diag::warn_cxx98_compat_template_arg_extra_parens
@@ -6684,8 +6680,13 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
     ValueDecl *VD = DRE->getDecl();
     if (VD->getType()->isMemberPointerType()) {
       if (isa<NonTypeTemplateParmDecl>(VD)) {
-        Converted = TemplateArgument(Arg);
-        return false;
+        if (Arg->isTypeDependent() || Arg->isValueDependent()) {
+          Converted = TemplateArgument(Arg);
+        } else {
+          VD = cast<ValueDecl>(VD->getCanonicalDecl());
+          Converted = TemplateArgument(VD, ParamType);
+        }
+        return Invalid;
       }
     }
 
@@ -6744,7 +6745,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
       ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
       Converted = TemplateArgument(D, S.Context.getCanonicalType(ParamType));
     }
-    return false;
+    return Invalid;
   }
 
   // We found something else, but we don't know specifically what it is.
@@ -6921,17 +6922,14 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     //   A template-argument for a non-type template parameter shall be
     //   a converted constant expression of the type of the template-parameter.
     APValue Value;
-    bool ValueDependent = false;
     ExprResult ArgResult = CheckConvertedConstantExpression(
-        Arg, ParamType, Value, CCEK_TemplateArg, Param, &ValueDependent);
+        Arg, ParamType, Value, CCEK_TemplateArg, Param);
     if (ArgResult.isInvalid())
       return ExprError();
 
     // For a value-dependent argument, CheckConvertedConstantExpression is
-    // permitted (and expected) to be unable to determine a value. We might find
-    // the evaluated result refers to a dependent declaration even though the
-    // template argument is not a value-dependent expression.
-    if (ValueDependent) {
+    // permitted (and expected) to be unable to determine a value.
+    if (ArgResult.get()->isValueDependent()) {
       Converted = TemplateArgument(ArgResult.get());
       return ArgResult;
     }

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index cbf4fb1de465..39ea9e06e7b1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3227,8 +3227,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
       if (FunctionDecl *Pattern =
               Function->getInstantiatedFromMemberFunction()) {
 
-        if (TSK != TSK_ImplicitInstantiation &&
-            Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+        if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
           continue;
 
         MemberSpecializationInfo *MSInfo =
@@ -3273,8 +3272,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
         continue;
 
       if (Var->isStaticDataMember()) {
-        if (TSK != TSK_ImplicitInstantiation &&
-            Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+        if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
           continue;
 
         MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
@@ -3291,7 +3289,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
             SuppressNew)
           continue;
 
-        if (TSK != TSK_ExplicitInstantiationDeclaration) {
+        if (TSK == TSK_ExplicitInstantiationDefinition) {
           // C++0x [temp.explicit]p8:
           //   An explicit instantiation definition that names a class template
           //   specialization explicitly instantiates the class template

diff  --git a/clang/test/OpenMP/distribute_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_dist_schedule_messages.cpp
index 0f7b2172f5a5..cd232f40feb4 100644
--- a/clang/test/OpenMP/distribute_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_dist_schedule_messages.cpp
@@ -35,7 +35,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
   #pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i) foo();
-  #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
   return T();
 }

diff  --git a/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
index 18dcac555f74..07e7704dffde 100644
--- a/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
@@ -54,7 +54,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
   return T();
 }

diff  --git a/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
index 63f8cfe917cd..ed7b19111dee 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
   return T();
 }

diff  --git a/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
index a6593cfbe0d3..794681c02646 100644
--- a/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
@@ -63,7 +63,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 #pragma omp target
 #pragma omp teams
-#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
   return T();
 }

diff  --git a/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
index f829874864da..7acb2587f976 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
@@ -46,7 +46,7 @@ T tmain(T argc, S **argv) {
   #pragma omp target parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
 
-  // expected-error at +1 1+{{integral constant expression}} expected-note at +1 0+{{constant expression}}
+  // expected-error at +1 {{integral constant expression}} expected-note at +1 0+{{constant expression}}
   #pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp target parallel for simd collapse (1)

diff  --git a/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
index 972aa5753e36..8dd7f68c25fd 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
@@ -56,7 +56,7 @@ T tmain(T argc, S **argv) {
   for (int i = ST; i < N; i++)
     argv[0][i] = argv[0][i] - argv[0][i - ST];
 
-// expected-error at +1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
+// expected-error at +1 {{integral constant expression}} expected-note at +1 0+{{constant expression}}
 #pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = ST; i < N; i++)
     argv[0][i] = argv[0][i] - argv[0][i - ST];

diff  --git a/clang/test/OpenMP/target_simd_collapse_messages.cpp b/clang/test/OpenMP/target_simd_collapse_messages.cpp
index d8b0a91f97d7..00fa3c85279f 100644
--- a/clang/test/OpenMP/target_simd_collapse_messages.cpp
+++ b/clang/test/OpenMP/target_simd_collapse_messages.cpp
@@ -44,7 +44,7 @@ T tmain(T argc, S **argv) {
   #pragma omp target simd collapse (S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
 
-  // expected-error at +1 1+{{integral constant expression}} expected-note at +1 0+{{constant expression}}
+  // expected-error at +1 {{integral constant expression}} expected-note at +1 0+{{constant expression}}
   #pragma omp target simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp target simd collapse (1)

diff  --git a/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
index e31df97ba31c..69c1e55eeaa3 100644
--- a/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
 #pragma omp target teams distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i) foo();
 
-#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
index 4f3c58125446..a0efad18668e 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
 #pragma omp target teams distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i) foo();
 
-#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
index 8b272d4358f6..ec634c8ac01c 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
 #pragma omp target teams distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i) foo();
 
-#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
index b583c14831e7..507ddabd2fc2 100644
--- a/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_messages.cpp
@@ -45,7 +45,7 @@ T tmain(T argc) {
 #pragma omp target teams distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
   for (int i = 0; i < 10; ++i) foo();
 
-#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/target_update_from_messages.cpp b/clang/test/OpenMP/target_update_from_messages.cpp
index 42ecc2814e12..3dc377c4ca4c 100644
--- a/clang/test/OpenMP/target_update_from_messages.cpp
+++ b/clang/test/OpenMP/target_update_from_messages.cpp
@@ -131,7 +131,7 @@ T tmain(T argc) {
 #pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
 #pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
 #pragma omp target update from(s7.p[:10])
-#pragma omp target update from(x, s7.bfa) // expected-error 2{{bit fields cannot be used to specify storage in a 'from' clause}}
+#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}}
 #pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
 #pragma omp target data map(to: s7.i)
   {

diff  --git a/clang/test/OpenMP/target_update_to_messages.cpp b/clang/test/OpenMP/target_update_to_messages.cpp
index 941c781119e6..fca4e21304fc 100644
--- a/clang/test/OpenMP/target_update_to_messages.cpp
+++ b/clang/test/OpenMP/target_update_to_messages.cpp
@@ -138,7 +138,7 @@ T tmain(T argc) {
 #pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
 #pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
 #pragma omp target update to(s7.p[:10])
-#pragma omp target update to(x, s7.bfa) // expected-error 2{{bit fields cannot be used to specify storage in a 'to' clause}}
+#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
 #pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
 #pragma omp target data map(to: s7.i)
   {

diff  --git a/clang/test/OpenMP/task_messages.cpp b/clang/test/OpenMP/task_messages.cpp
index 2f9ee9a44402..13cbfb6c4569 100644
--- a/clang/test/OpenMP/task_messages.cpp
+++ b/clang/test/OpenMP/task_messages.cpp
@@ -156,11 +156,11 @@ int foo() {
 #pragma omp task detach(a) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'int'}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'S'}}
   ;
 #pragma omp task detach(evt) detach(evt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}}
-#pragma omp task detach(cevt) detach(revt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}}
+#pragma omp task detach(cevt) detach(revt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'const omp_event_handle_t' (aka 'const unsigned long')}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'omp_event_handle_t &' (aka 'unsigned long &')}}
 #pragma omp task detach(evt) mergeable // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{'mergeable' and 'detach' clause are mutually exclusive and may not appear on the same directive}} omp50-note {{'detach' clause is specified here}}
   ;
 #pragma omp task mergeable detach(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{'detach' and 'mergeable' clause are mutually exclusive and may not appear on the same directive}} omp50-note {{'mergeable' clause is specified here}}
-#pragma omp task detach(-evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
+#pragma omp task detach(-evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{expected variable of the 'omp_event_handle_t' type}}
   ;
 #pragma omp task detach(evt) shared(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
 #pragma omp task detach(evt) firstprivate(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}

diff  --git a/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
index bd1aaa5c6289..22d2408d3f17 100644
--- a/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
index a70d80ad1251..27ff4125daf7 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
index b87301fa98d8..cbd4ec4ce979 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
index 6e653fae08c8..424797576837 100644
--- a/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_dist_schedule_messages.cpp
@@ -55,7 +55,7 @@ T tmain(T argc) {
   for (int i = 0; i < 10; ++i) foo();
 
 #pragma omp target
-#pragma omp teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
   for (int i = 0; i < 10; ++i) foo();
 
   return T();

diff  --git a/clang/test/SemaCXX/warn-unused-lambda-capture.cpp b/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
index 764a4a42a084..52ec390b0bba 100644
--- a/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
+++ b/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
@@ -147,7 +147,7 @@ void test_templated() {
 
   auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
   auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
-  auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+  auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
   auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
   auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
 

diff  --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
similarity index 98%
rename from clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp
rename to clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index 52cf51719f05..675f957ef6fa 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx17.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -503,13 +503,3 @@ namespace PR48517 {
   template<> struct Q<&R<int>::n> { static constexpr int X = 1; };
   static_assert(R<int>().f() == 1);
 }
-
-namespace dependent_reference {
-  template<int &r> struct S { int *q = &r; };
-  template<int> auto f() { static int n; return S<n>(); }
-  auto v = f<0>();
-  auto w = f<1>();
-  static_assert(!is_same<decltype(v), decltype(w)>);
-  // Ensure that we can instantiate the definition of S<...>.
-  int n = *v.q + *w.q;
-}

diff  --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
index d514465f7d67..c42fda780430 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
@@ -292,47 +292,3 @@ namespace Predefined {
     Y<B{__func__[0]}>(); // expected-error {{reference to subobject of predefined '__func__' variable}}
   }
 }
-
-namespace dependent {
-  template<auto &V> struct R { static inline auto &v = V; };
-  template<auto &V, auto &W> constexpr bool operator==(R<V>, R<W>) { return &V == &W; }
-  template<auto *V> struct S { static inline auto *v = V; };
-  template<auto *V, auto *W> constexpr bool operator==(S<V>, S<W>) { return V == W; }
-  template<auto V> struct T { static inline const auto &v = V; };
-  template<auto V, auto W> constexpr bool operator==(T<V>, T<W>) { return &V == &W; }
-  template<typename T> struct V { T v; };
-  template<int N> auto f() {
-    static int n;
-    static V<int> vn;
-    if constexpr (N < 10)
-      return R<n>();
-    else if constexpr (N < 20)
-      return R<vn.v>(); // FIXME: expected-error 2{{refers to subobject}}
-    else if constexpr (N < 30)
-      return S<&n>();
-    else if constexpr (N < 40)
-      return S<&vn.v>(); // FIXME: expected-error 2{{refers to subobject}}
-    else if constexpr (N < 50)
-      return T<V<int&>{n}>();
-    else if constexpr (N < 60)
-      return T<V<int*>{&n}>();
-    else if constexpr (N < 70)
-      return T<V<int&>{vn.v}>();
-    else if constexpr (N < 80)
-      return T<V<int*>{&vn.v}>();
-  }
-  template<int Base> void check() {
-    auto v = f<Base + 0>(); // FIXME: expected-note 2{{instantiation of}}
-    auto w = f<Base + 1>(); // FIXME: expected-note 2{{instantiation of}}
-    static_assert(!__is_same(decltype(v), decltype(w)));
-    static_assert(v != w);
-  }
-  template void check<0>();
-  template void check<10>(); // FIXME: expected-note 2{{instantiation of}}
-  template void check<20>();
-  template void check<30>(); // FIXME: expected-note 2{{instantiation of}}
-  template void check<40>();
-  template void check<50>();
-  template void check<60>();
-  template void check<70>();
-}


        


More information about the llvm-branch-commits mailing list