diff options
| author | Nico Weber <nicolasweber@gmx.de> | 2010-11-29 18:19:25 +0000 |
|---|---|---|
| committer | Nico Weber <nicolasweber@gmx.de> | 2010-11-29 18:19:25 +0000 |
| commit | 44887f69d52ee2cba26a6fc8ce7206dac5efb69e (patch) | |
| tree | 03d1a4a31ad5ba86dfc737f0c4608e0509cd0b2e | |
| parent | 447762da858c1705c5fce5288f874797dc4b1135 (diff) | |
| download | bcm5719-llvm-44887f69d52ee2cba26a6fc8ce7206dac5efb69e.tar.gz bcm5719-llvm-44887f69d52ee2cba26a6fc8ce7206dac5efb69e.zip | |
Always use a function's decl context when building default arguments. Fixes http://http://llvm.org/pr8479.
llvm-svn: 120299
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 16 | ||||
| -rw-r--r-- | clang/test/SemaCXX/friend.cpp | 33 |
2 files changed, 45 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 087314fbcba..e8025409bd6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3839,8 +3839,8 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, } ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, - FunctionDecl *FD, - ParmVarDecl *Param) { + FunctionDecl *FD, + ParmVarDecl *Param) { if (Param->hasUnparsedDefaultArg()) { Diag(CallLoc, diag::err_use_of_default_argument_to_function_declared_later) << @@ -3857,12 +3857,20 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, MultiLevelTemplateArgumentList ArgList = getTemplateInstantiationArgs(FD, 0, /*RelativeToPrimary=*/true); - std::pair<const TemplateArgument *, unsigned> Innermost + std::pair<const TemplateArgument *, unsigned> Innermost = ArgList.getInnermost(); InstantiatingTemplate Inst(*this, CallLoc, Param, Innermost.first, Innermost.second); - ExprResult Result = SubstExpr(UninstExpr, ArgList); + ExprResult Result; + { + // C++ [dcl.fct.default]p5: + // The names in the [default argument] expression are bound, and + // the semantic constraints are checked, at the point where the + // default argument expression appears. + ContextRAII SavedContext(*this, FD->getDeclContext()); + Result = SubstExpr(UninstExpr, ArgList); + } if (Result.isInvalid()) return ExprError(); diff --git a/clang/test/SemaCXX/friend.cpp b/clang/test/SemaCXX/friend.cpp index 939d3ae4568..515edfd949f 100644 --- a/clang/test/SemaCXX/friend.cpp +++ b/clang/test/SemaCXX/friend.cpp @@ -79,3 +79,36 @@ namespace test5 { struct B { friend void B(); }; } + +// PR8479 +namespace test6_1 { + class A { + public: + private: + friend class vectorA; + A() {} + }; + class vectorA { + public: + vectorA(int i, const A& t = A()) {} + }; + void f() { + vectorA v(1); + } +} +namespace test6_2 { + template<class T> + class vector { + public: + vector(int i, const T& t = T()) {} + }; + class A { + public: + private: + friend class vector<A>; + A() {} + }; + void f() { + vector<A> v(1); + } +} |

