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;
}
}
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;
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits