[PATCH] D65022: [Sema] Always instantiate the initializer of a variable template with undeduced type (8.0 regression)

Erik Pilkington via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 30 16:53:03 PDT 2019


erik.pilkington updated this revision to Diff 212470.
erik.pilkington added a comment.

Rebase on top of r367367.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65022/new/

https://reviews.llvm.org/D65022

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprMember.cpp
  clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp


Index: clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
===================================================================
--- clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -424,3 +424,34 @@
 }
 }
 #endif
+
+#ifndef PRECXX11
+namespace auto_variable_instantiate_initializer {
+template <class T2> struct S {
+  template <class T> static constexpr auto v = 1;
+  template <class T> static constexpr auto v2 = T{};
+
+  template <class T, int i = v<T>>
+  void implicit() {
+    double d = v2<T>;
+    int i2 = v<short>;
+  }
+
+  void implicit_nondep() {
+    int i = v<unsigned char>;
+    double d = v2<signed char>;
+  }
+};
+
+void useit() {
+  S<int> x;
+  // We used to fail to instantiate the initializer, leading to an auto type
+  // leaking through here.
+  int i = x.v<float>;
+  float j = x.v2<float>;
+
+  x.implicit<double>();
+  x.implicit_nondep();
+}
+}
+ #endif
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ clang/lib/Sema/SemaExprMember.cpp
@@ -1160,11 +1160,17 @@
   }
   if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
     if (VarDecl *Var = getVarTemplateSpecialization(
-            VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc))
-      return BuildMemberExpr(
+            VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc)) {
+      MemberExpr *ME = BuildMemberExpr(
           BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var, FoundDecl,
           /*HadMultipleCandidates=*/false, MemberNameInfo,
           Var->getType().getNonReferenceType(), VK_LValue, OK_Ordinary);
+
+      // BuildMemberExpr may have deduced an auto variable's type. Patch back
+      // that type to avoid forming an expression with undeduced type.
+      ME->setType(Var->getType().getNonReferenceType());
+      return ME;
+    }
     return ExprError();
   }
 
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3163,9 +3163,15 @@
       break;
     }
 
-    return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD,
-                            /*FIXME: TemplateKWLoc*/ SourceLocation(),
-                            TemplateArgs);
+    DeclRefExpr *DRE = BuildDeclRefExpr(
+        VD, type, valueKind, NameInfo, &SS, FoundD,
+        /*FIXME: TemplateKWLoc*/ SourceLocation(), TemplateArgs);
+
+    // BuildDeclRefExpr may have deduced an auto variable's type. Patch back
+    // that type to avoid forming an expression with undeduced type.
+    if (isa<VarTemplateSpecializationDecl>(VD))
+      DRE->setType(VD->getType().getNonReferenceType());
+    return DRE;
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65022.212470.patch
Type: text/x-patch
Size: 2842 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190730/bd7d6d71/attachment.bin>


More information about the cfe-commits mailing list