r320709 - When attempting to complete an incomplete array bound type in an expression,

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 14 07:40:16 PST 2017


Author: rsmith
Date: Thu Dec 14 07:40:16 2017
New Revision: 320709

URL: http://llvm.org/viewvc/llvm-project?rev=320709&view=rev
Log:
When attempting to complete an incomplete array bound type in an expression,
update the type from the definition even if we didn't instantiate a definition.

We may have instantiated the definition in an earlier stage of semantic
analysis, after creating the DeclRefExpr but before we reach a point where a
complete expression type is required.

Modified:
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=320709&r1=320708&r2=320709&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Dec 14 07:40:16 2017
@@ -7268,27 +7268,29 @@ static void processTypeAttrs(TypeProcess
 void Sema::completeExprArrayBound(Expr *E) {
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
     if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
-      if (isTemplateInstantiation(Var->getTemplateSpecializationKind()) &&
-          !Var->getDefinition()) {
-        SourceLocation PointOfInstantiation = E->getExprLoc();
-        InstantiateVariableDefinition(PointOfInstantiation, Var);
+      if (isTemplateInstantiation(Var->getTemplateSpecializationKind())) {
         auto *Def = Var->getDefinition();
+        if (!Def) {
+          SourceLocation PointOfInstantiation = E->getExprLoc();
+          InstantiateVariableDefinition(PointOfInstantiation, Var);
+          Def = Var->getDefinition();
 
-        // If we don't already have a point of instantiation, and we managed to
-        // instantiate a definition, this is the point of instantiation.
-        // Otherwise, we don't request an end-of-TU instantiation, so this is
-        // not a point of instantiation.
-        // FIXME: Is this really the right behavior?
-        if (Var->getPointOfInstantiation().isInvalid() && Def) {
-          assert(Var->getTemplateSpecializationKind() ==
-                     TSK_ImplicitInstantiation &&
-                 "explicit instantiation with no point of instantiation");
-          Var->setTemplateSpecializationKind(
-              Var->getTemplateSpecializationKind(), PointOfInstantiation);
+          // If we don't already have a point of instantiation, and we managed
+          // to instantiate a definition, this is the point of instantiation.
+          // Otherwise, we don't request an end-of-TU instantiation, so this is
+          // not a point of instantiation.
+          // FIXME: Is this really the right behavior?
+          if (Var->getPointOfInstantiation().isInvalid() && Def) {
+            assert(Var->getTemplateSpecializationKind() ==
+                       TSK_ImplicitInstantiation &&
+                   "explicit instantiation with no point of instantiation");
+            Var->setTemplateSpecializationKind(
+                Var->getTemplateSpecializationKind(), PointOfInstantiation);
+          }
         }
 
-        // Update the type to the newly instantiated definition's type both
-        // here and within the expression.
+        // Update the type to the definition's type both here and within the
+        // expression.
         if (Def) {
           DRE->setDecl(Def);
           QualType T = Def->getType();

Modified: cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp?rev=320709&r1=320708&r2=320709&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp (original)
+++ cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp Thu Dec 14 07:40:16 2017
@@ -5,3 +5,14 @@ template<bool> struct DominatorTreeBase
 };
 extern template class DominatorTreeBase<false>;
 constexpr bool k = DominatorTreeBase<false>::IsPostDominator;
+
+namespace CompleteType {
+  template<unsigned N> constexpr int f(const bool (&)[N]) { return 0; }
+
+  template<bool ...V> struct X {
+    static constexpr bool arr[] = {V...};
+    static constexpr int value = f(arr);
+  };
+
+  constexpr int n = X<true>::value;
+}




More information about the cfe-commits mailing list