On Wed, Apr 4, 2012 at 2:44 PM, Nico Weber <[email protected]> wrote:
> Hi Richard, > > (below) > > On Wed, Apr 4, 2012 at 2:11 PM, Richard Smith > <[email protected]> wrote: > > Author: rsmith > > Date: Wed Apr 4 16:11:30 2012 > > New Revision: 154053 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=154053&view=rev > > Log: > > Implement C++11 [temp.arg.nontype]'s permission to use the address of an > object > > or function with internal linkage as a non-type template argument. > > > > Modified: > > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > > cfe/trunk/lib/Sema/SemaTemplate.cpp > > cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp > > cfe/trunk/test/CodeGenCXX/mangle-template.cpp > > cfe/trunk/test/SemaCXX/cxx98-compat.cpp > > > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=154053&r1=154052&r2=154053&view=diff > > > ============================================================================== > > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 4 > 16:11:30 2012 > > @@ -2361,11 +2361,18 @@ > > "non-type template argument refers to non-static data member %0">; > > def err_template_arg_method : Error< > > "non-type template argument refers to non-static member function %0">; > > -def err_template_arg_function_not_extern : Error< > > - "non-type template argument refers to function %0 with internal > linkage">; > > -def err_template_arg_object_not_extern : Error< > > - "non-type template argument refers to object %0 that does not have > external " > > - "linkage">; > > +def err_template_arg_object_no_linkage : Error< > > + "non-type template argument refers to %select{function|object}0 %1 > that " > > + "does not have linkage">; > > +def warn_cxx98_compat_template_arg_object_internal : Warning< > > + "non-type template argument referring to %select{function|object}0 %1 > with " > > + "internal linkage is incompatible with C++98">, > > + InGroup<CXX98Compat>, DefaultIgnore; > > +def ext_template_arg_object_internal : ExtWarn< > > + "non-type template argument referring to %select{function|object}0 %1 > with " > > + "internal linkage is a C++11 extension">, InGroup<CXX11>; > > +def err_template_arg_thread_local : Error< > > + "non-type template argument refers to thread-local object">; > > def note_template_arg_internal_object : Note< > > "non-type template argument refers to %select{function|object}0 here">; > > def note_template_arg_refers_here : Note< > > > > Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=154053&r1=154052&r2=154053&view=diff > > > ============================================================================== > > --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 4 16:11:30 2012 > > @@ -3550,10 +3550,10 @@ > > return true; > > } > > > > - NamedDecl *Entity = 0; > > + NamedDecl *Entity = DRE->getDecl(); > > > > // Cannot refer to non-static data members > > - if (FieldDecl *Field = dyn_cast<FieldDecl>(DRE->getDecl())) { > > + if (FieldDecl *Field = dyn_cast<FieldDecl>(Entity)) { > > S.Diag(Arg->getLocStart(), diag::err_template_arg_field) > > << Field << Arg->getSourceRange(); > > S.Diag(Param->getLocation(), diag::note_template_param_here); > > @@ -3561,28 +3561,44 @@ > > } > > > > // Cannot refer to non-static member functions > > - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(DRE->getDecl())) > > + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Entity)) { > > if (!Method->isStatic()) { > > S.Diag(Arg->getLocStart(), diag::err_template_arg_method) > > << Method << Arg->getSourceRange(); > > S.Diag(Param->getLocation(), diag::note_template_param_here); > > return true; > > } > > + } > > > > - // Functions must have external linkage. > > - if (FunctionDecl *Func = dyn_cast<FunctionDecl>(DRE->getDecl())) { > > - if (!isExternalLinkage(Func->getLinkage())) { > > - S.Diag(Arg->getLocStart(), > > - diag::err_template_arg_function_not_extern) > > - << Func << Arg->getSourceRange(); > > - S.Diag(Func->getLocation(), > diag::note_template_arg_internal_object) > > - << true; > > - return true; > > - } > > + FunctionDecl *Func = dyn_cast<FunctionDecl>(Entity); > > + VarDecl *Var = dyn_cast<VarDecl>(Entity); > > + > > + // A non-type template argument must refer to an object or function. > > + if (!Func && !Var) { > > + // We found something, but we don't know specifically what it is. > > + S.Diag(Arg->getLocStart(), > diag::err_template_arg_not_object_or_func) > > + << Arg->getSourceRange(); > > + S.Diag(DRE->getDecl()->getLocation(), > diag::note_template_arg_refers_here); > > + return true; > > + } > > > > - // Okay: we've named a function with external linkage. > > - Entity = Func; > > + // Address / reference template args must have external linkage in > C++98. > > + if (Entity->getLinkage() == InternalLinkage) { > > + S.Diag(Arg->getLocStart(), S.getLangOpts().CPlusPlus0x ? > > + diag::warn_cxx98_compat_template_arg_object_internal : > > + diag::ext_template_arg_object_internal) > > + << !Func << Entity << Arg->getSourceRange(); > > + S.Diag(Entity->getLocation(), > diag::note_template_arg_internal_object) > > + << !Func; > > + } else if (Entity->getLinkage() == NoLinkage) { > > + S.Diag(Arg->getLocStart(), diag::err_template_arg_object_no_linkage) > > + << !Func << Entity << Arg->getSourceRange(); > > + S.Diag(Entity->getLocation(), > diag::note_template_arg_internal_object) > > + << !Func; > > + return true; > > + } > > > > + if (Func) { > > // If the template parameter has pointer type, the function decays. > > if (ParamType->isPointerType() && !AddressTaken) > > ArgType = S.Context.getPointerType(Func->getType()); > > @@ -3605,16 +3621,7 @@ > > > > ArgType = Func->getType(); > > } > > - } else if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) { > > - if (!isExternalLinkage(Var->getLinkage())) { > > - S.Diag(Arg->getLocStart(), > > - diag::err_template_arg_object_not_extern) > > - << Var << Arg->getSourceRange(); > > - S.Diag(Var->getLocation(), > diag::note_template_arg_internal_object) > > - << true; > > - return true; > > - } > > - > > + } else { > > // A value of reference type is not an object. > > if (Var->getType()->isReferenceType()) { > > S.Diag(Arg->getLocStart(), > > @@ -3624,8 +3631,14 @@ > > return true; > > } > > > > - // Okay: we've named an object with external linkage > > - Entity = Var; > > + // A template argument must have static storage duration. > > + // FIXME: Ensure this works for thread_local as well as __thread. > > + if (Var->isThreadSpecified()) { > > + S.Diag(Arg->getLocStart(), diag::err_template_arg_thread_local) > > + << Arg->getSourceRange(); > > + S.Diag(Var->getLocation(), diag::note_template_arg_refers_here); > > + return true; > > + } > > > > // If the template parameter has pointer type, we must have taken > > // the address of this object. > > @@ -3672,13 +3685,6 @@ > > S.Diag(Param->getLocation(), diag::note_template_param_here); > > } > > } > > - } else { > > - // We found something else, but we don't know specifically what it > is. > > - S.Diag(Arg->getLocStart(), > > - diag::err_template_arg_not_object_or_func) > > - << Arg->getSourceRange(); > > - S.Diag(DRE->getDecl()->getLocation(), > diag::note_template_arg_refers_here); > > - return true; > > } > > > > bool ObjCLifetimeConversion; > > > > Modified: cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp?rev=154053&r1=154052&r2=154053&view=diff > > > ============================================================================== > > --- cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp (original) > > +++ cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp Wed Apr 4 > 16:11:30 2012 > > @@ -1,6 +1,6 @@ > > // RUN: %clang_cc1 -fsyntax-only -verify %s > > > > -// C++0x [temp.arg.nontype]p1: > > +// C++11 [temp.arg.nontype]p1: > > // > > // A template-argument for a non-type, non-template > template-parameter shall > > // be one of: > > @@ -19,27 +19,65 @@ > > template <typename T, int (T::* M)(int)> X5<T, M>::X5() { } > > } > > > > -// -- the address of an object or function with external linkage, > including > > -// function templates and function template-ids but excluding > non-static > > -// class members, expressed as & id-expression where the & is > optional if > > -// the name refers to a function or array, or if the corresponding > > -// template-parameter is a reference; or > > +// -- a constant expression that designates the address of an object > with > > +// static storage duration and external or internal linkage or a > function > > +// with external or internal linkage, including function templates > and > > +// function template-ids, but excluting non-static class members, > expressed > > +// (ignoring parentheses) as & id-expression, except that the & > may be > > +// omitted if the name refers to a function or array and shall be > omitted > > +// if the corresopnding template-parameter is a reference; or > > namespace addr_of_obj_or_func { > > - template <int* p> struct X0 { }; > > + template <int* p> struct X0 { }; // expected-note 4{{here}} > > template <int (*fp)(int)> struct X1 { }; > > - // FIXME: Add reference template parameter tests. > > + template <int &p> struct X2 { }; // expected-note 4{{here}} > > + template <const int &p> struct X2k { }; // expected-note {{here}} > > + template <int (&fp)(int)> struct X3 { }; // expected-note 4{{here}} > > > > int i = 42; > > int iarr[10]; > > int f(int i); > > + const int ki = 9; // expected-note 5{{here}} > > + __thread int ti = 100; // expected-note 2{{here}} > > Fails like this on mac: > > ******************** TEST 'Clang :: > CXX/temp/temp.arg/temp.arg.nontype/p1.cpp' FAILED ******************** > Script: > -- > /Volumes/MacintoshHD2/src/llvm-svn/Release+Asserts/bin/clang -cc1 > -internal-isystem > > /Volumes/MacintoshHD2/src/llvm-svn/Release+Asserts/bin/../lib/clang/3.1/include > -fsyntax-only -verify > > /Volumes/MacintoshHD2/src/llvm-svn/tools/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp > -- > Exit Code: 1 > Command Output (stderr): > -- > error: 'error' diagnostics expected but not seen: > Line 51: refers to thread-local object > Line 67: refers to thread-local object > error: 'error' diagnostics seen but not expected: > Line 40: thread-local storage is unsupported for the current target > error: 'note' diagnostics expected but not seen: > Line 40: here > Line 40: here > 5 errors generated. > Thanks, does r154058 help?
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
