timshen created this revision.
Herald added a subscriber: sanjoy.
The mis-compile is triggered by internal code, but I haven't reduced it to a
small piece of code. Add a FIXME here, since a decent fix doesn't seem to be
trivial.
The decent fix can be changing Decl::Init to PointerUnion<Stmt *, EvaluatedStmt
*, ParamVarDecl *>, and make setUninstantiatedDefaultArg take a ParamVarDecl *,
which contains the Expr * as the default argument. This way,
getTemplateInstantiationArgs can take that ParamVarDecl and do the right thing.
https://reviews.llvm.org/D36253
Files:
clang/lib/Sema/SemaExpr.cpp
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4477,6 +4477,22 @@
*this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
// Instantiate the expression.
+ //
+ // FIXME: Pass in a correct Pattern argument, otherwise
+ // getTemplateInstantiationArgs uses the lexical context of FD, e.g.
+ //
+ // template<typename T>
+ // struct A {
+ // static int FooImpl();
+ //
+ // template<typename Tp>
+ // // bug: default argument A<T>::FooImpl() is evaluated with 2-level
+ // // template argument list [[T], [Tp]], should be [[Tp]].
+ // friend A<Tp> Foo(int a);
+ // };
+ //
+ // template<typename T>
+ // A<T> Foo(int a = A<T>::FooImpl());
MultiLevelTemplateArgumentList MutiLevelArgList
= getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true);
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4477,6 +4477,22 @@
*this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
// Instantiate the expression.
+ //
+ // FIXME: Pass in a correct Pattern argument, otherwise
+ // getTemplateInstantiationArgs uses the lexical context of FD, e.g.
+ //
+ // template<typename T>
+ // struct A {
+ // static int FooImpl();
+ //
+ // template<typename Tp>
+ // // bug: default argument A<T>::FooImpl() is evaluated with 2-level
+ // // template argument list [[T], [Tp]], should be [[Tp]].
+ // friend A<Tp> Foo(int a);
+ // };
+ //
+ // template<typename T>
+ // A<T> Foo(int a = A<T>::FooImpl());
MultiLevelTemplateArgumentList MutiLevelArgList
= getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits