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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits