diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-04-30 21:46:38 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-04-30 21:46:38 +0000 |
| commit | fabf95d0667b5dcc9da3d5537f1d3ca20b2914b5 (patch) | |
| tree | 86f10c0aa1ddce026ebeea83e3e68cbc40cc19cb /clang | |
| parent | 4d4dcc8ed7441ceda5b975e7a1a0ead0a2ab86b2 (diff) | |
| download | bcm5719-llvm-fabf95d0667b5dcc9da3d5537f1d3ca20b2914b5.tar.gz bcm5719-llvm-fabf95d0667b5dcc9da3d5537f1d3ca20b2914b5.zip | |
After substituting a template argument for a non-type template
parameter with pointer-to-member type, we may have to perform a
qualification conversion, since the pointee type of the parameter
might be more qualified than the pointee type of the argument we form
from the declaration. Fixes PR6986.
llvm-svn: 102777
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 14 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp | 24 |
2 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index db9ed7e1efc..56410a2cfa4 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3061,9 +3061,21 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, return ExprError(); RefExpr = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr)); + + // We might need to perform a trailing qualification conversion, since + // the element type on the parameter could be more qualified than the + // element type in the expression we constructed. + if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(), + ParamType.getUnqualifiedType())) { + Expr *RefE = RefExpr.takeAs<Expr>(); + ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), + CastExpr::CK_NoOp); + RefExpr = Owned(RefE); + } + assert(!RefExpr.isInvalid() && Context.hasSameType(((Expr*) RefExpr.get())->getType(), - ParamType)); + ParamType.getUnqualifiedType())); return move(RefExpr); } } diff --git a/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp b/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp index 414e62b13a0..cbadcde2c1c 100644 --- a/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp +++ b/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp @@ -9,6 +9,28 @@ public: } }; -int main(int argc, char *argv[]) { +void test_stringswitch(int argc, char *argv[]) { (void)StringSwitch<int>(); } + +namespace PR6986 { + template<class Class,typename Type,Type Class::*> + struct non_const_member_base + { + }; + + template<class Class,typename Type,Type Class::*PtrToMember> + struct member: non_const_member_base<Class,Type,PtrToMember> + { + }; + + struct test_class + { + int int_member; + }; + typedef member< test_class,const int,&test_class::int_member > ckey_m; + void test() + { + ckey_m m; + } +} |

