[cfe-commits] r154053 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp test/CodeGenCXX/mangle-template.cpp test/SemaCXX/cxx98-compat.cpp
Richard Smith
richard at metafoo.co.uk
Wed Apr 4 14:54:43 PDT 2012
On Wed, Apr 4, 2012 at 2:44 PM, Nico Weber <thakis at chromium.org> wrote:
> Hi Richard,
>
> (below)
>
> On Wed, Apr 4, 2012 at 2:11 PM, Richard Smith
> <richard-llvm at metafoo.co.uk> 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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120404/bc6b723d/attachment.html>
More information about the cfe-commits
mailing list