[cfe-commits] r151001 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplate.cpp test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Mon Feb 20 15:28:05 PST 2012
Author: rsmith
Date: Mon Feb 20 17:28:05 2012
New Revision: 151001
URL: http://llvm.org/viewvc/llvm-project?rev=151001&view=rev
Log:
Fix a constexpr FIXME: When implicitly instantiating the primary template for an
explicit specialization of a function template, mark the instantiation as
constexpr if the specialization is, rather than requiring them to match.
Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=151001&r1=151000&r2=151001&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Feb 20 17:28:05 2012
@@ -516,13 +516,9 @@
}
}
- // C++0x [dcl.constexpr]p1: If any declaration of a function or function
+ // C++11 [dcl.constexpr]p1: If any declaration of a function or function
// template has a constexpr specifier then all its declarations shall
- // contain the constexpr specifier. [Note: An explicit specialization can
- // differ from the template declaration with respect to the constexpr
- // specifier. -- end note]
- //
- // FIXME: Don't reject changes in constexpr in explicit specializations.
+ // contain the constexpr specifier.
if (New->isConstexpr() != Old->isConstexpr()) {
Diag(New->getLocation(), diag::err_constexpr_redecl_mismatch)
<< New << New->isConstexpr();
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=151001&r1=151000&r2=151001&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Feb 20 17:28:05 2012
@@ -5677,8 +5677,13 @@
// Note: do not overwrite location info if previous template
// specialization kind was explicit.
TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind();
- if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation)
+ if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) {
Specialization->setLocation(FD->getLocation());
+ // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr
+ // function can differ from the template declaration with respect to
+ // the constexpr specifier.
+ Specialization->setConstexpr(FD->isConstexpr());
+ }
// FIXME: Check if the prior specialization has a point of instantiation.
// If so, we have run afoul of .
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp?rev=151001&r1=151000&r2=151001&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp Mon Feb 20 17:28:05 2012
@@ -75,15 +75,13 @@
};
// explicit specialization can differ in constepxr
-// FIXME: When checking the explicit specialization, we implicitly instantiate
-// the primary template then claim a constexpr mismatch.
-template <> notlit ft(notlit nl) { return nl; } // unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
-template <> char ft(char c) { return c; } // desired-note {{previous}} unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
-template <> constexpr char ft(char nl); // desired-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
-template <> constexpr int gt(int nl) { return nl; } // unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}}
-template <> notlit S::f() const { return notlit(); } // unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
-template <> constexpr int S::g() { return 0; } // desired-note {{previous}} unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}}
-template <> int S::g() const; // desired-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
+template <> notlit ft(notlit nl) { return nl; }
+template <> char ft(char c) { return c; } // expected-note {{previous}}
+template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
+template <> constexpr int gt(int nl) { return nl; }
+template <> notlit S::f() const { return notlit(); }
+template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
// specializations can drop the 'constexpr' but not the implied 'const'.
template <> char S::g() { return 0; } // expected-error {{no function template matches}}
template <> double S::g() const { return 0; } // ok
More information about the cfe-commits
mailing list