From: Chandler Carruth Date: Sun, 31 Jan 2010 07:09:11 +0000 (+0000) Subject: Handle instantiation of templates with non-type arguments expressed with an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=548028b3ca15926c6883357e111b47bbc56a4761;p=clang Handle instantiation of templates with non-type arguments expressed with an explicit '&' by introducing an address-of operator prior to checking the argument's type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94947 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 2db0deb509..3efb52e91b 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -746,6 +746,22 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) { move(RefExpr)); } } + if (NTTP->getType()->isPointerType() && + !VD->getType()->isPointerType()) { + // If the template argument is expected to be a pointer and value + // isn't inherently of pointer type, then it is specified with '&...' + // to indicate its address should be used. Build an expression to + // take the address of the argument. + OwningExprResult RefExpr + = SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), + E->getLocation()); + if (RefExpr.isInvalid()) + return SemaRef.ExprError(); + + return SemaRef.CreateBuiltinUnaryOp(E->getLocation(), + UnaryOperator::AddrOf, + move(RefExpr)); + } return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), E->getLocation()); diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp new file mode 100644 index 0000000000..f9834dfed2 --- /dev/null +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template struct X { }; + +int i = 42; +int* iptr = &i; +void test() { + X<&i> x1; + X x2; +}