r221448 - Fix for exception specification mismatch in explicit instantiation.
Alexey Bataev
a.bataev at hotmail.com
Thu Nov 6 02:10:51 PST 2014
Author: abataev
Date: Thu Nov 6 04:10:50 2014
New Revision: 221448
URL: http://llvm.org/viewvc/llvm-project?rev=221448&view=rev
Log:
Fix for exception specification mismatch in explicit instantiation.
According to C++ standard if an exception-specification is specified in an explicit instantiation directive, it shall be compatible with the exception-specifications of other declarations of that function. This patch adds checks for this.
Differential Revision: http://reviews.llvm.org/D5822
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=221448&r1=221447&r2=221448&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Nov 6 04:10:50 2014
@@ -3658,6 +3658,11 @@ def err_invalid_var_template_spec_type :
"of %select{explicit instantiation|explicit specialization|"
"partial specialization|redeclaration}0 of %1 does not match"
" expected type %3">;
+def err_mismatched_exception_spec_explicit_instantiation : Error<
+ "exception specification in explicit instantiation does not match instantiated one">;
+def ext_mismatched_exception_spec_explicit_instantiation : ExtWarn<
+ "exception specification in explicit instantiation does not match instantiated one">,
+ InGroup<Microsoft>;
// C++ typename-specifiers
def err_typename_nested_not_found : Error<"no type named %0 in %1">;
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=221448&r1=221447&r2=221448&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Nov 6 04:10:50 2014
@@ -7627,6 +7627,29 @@ DeclResult Sema::ActOnExplicitInstantiat
// Ignore access control bits, we don't need them for redeclaration checking.
FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
+ // C++11 [except.spec]p4
+ // In an explicit instantiation an exception-specification may be specified,
+ // but is not required.
+ // If an exception-specification is specified in an explicit instantiation
+ // directive, it shall be compatible with the exception-specifications of
+ // other declarations of that function.
+ if (auto *FPT = R->getAs<FunctionProtoType>())
+ if (FPT->hasExceptionSpec()) {
+ unsigned DiagID =
+ diag::err_mismatched_exception_spec_explicit_instantiation;
+ if (getLangOpts().MicrosoftExt)
+ DiagID = diag::ext_mismatched_exception_spec_explicit_instantiation;
+ bool Result = CheckEquivalentExceptionSpec(
+ PDiag(DiagID) << Specialization->getType(),
+ PDiag(diag::note_explicit_instantiation_here),
+ Specialization->getType()->getAs<FunctionProtoType>(),
+ Specialization->getLocation(), FPT, D.getLocStart());
+ // In Microsoft mode, mismatching exception specifications just cause a
+ // warning.
+ if (!getLangOpts().MicrosoftExt && Result)
+ return true;
+ }
+
if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) {
Diag(D.getIdentifierLoc(),
diag::err_explicit_instantiation_member_function_not_instantiated)
Modified: cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp?rev=221448&r1=221447&r2=221448&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp (original)
+++ cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp Thu Nov 6 04:10:50 2014
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions -fcxx-exceptions -std=c++11 %s
template void *; // expected-error{{expected unqualified-id}}
@@ -13,8 +14,8 @@ struct X0 {
T f0(T x) {
return x + 1; // expected-error{{invalid operands}}
- }
- T* f0(T*, T*) { return T(); } // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+ }
+ T *f0(T *, T *) { return T(); } // expected-warning 0-1 {{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} expected-error 0-1 {{cannot initialize return object of type 'int *' with an rvalue of type 'int'}}
template <typename U> T f0(T, U) { return T(); } // expected-note-re {{candidate template ignored: could not match 'int (int, U){{( __attribute__\(\(thiscall\)\))?}}' against 'int (int){{( __attribute__\(\(thiscall\)\))?}} const'}} \
// expected-note {{candidate template ignored: could not match 'int' against 'int *'}}
@@ -25,7 +26,7 @@ T X0<T>::value; // expected-error{{no ma
template int X0<int>::value;
-struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}}
+struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}} expected-note 0-1 {{candidate constructor (the implicit move constructor)}}
NotDefaultConstructible(int); // expected-note{{candidate constructor}}
};
@@ -149,3 +150,17 @@ namespace undefined_static_data_member {
template int C<int>::b<int>;
template int D::c<int>;
}
+
+// expected-note at +1 3-4 {{explicit instantiation refers here}}
+template <class T> void Foo(T i) throw(T) { throw i; }
+// expected-error at +1 {{exception specification in explicit instantiation does not match instantiated one}}
+template void Foo(int a) throw(char);
+// expected-error at +1 {{exception specification in explicit instantiation does not match instantiated one}}
+template void Foo(double a) throw();
+// expected-error at +1 1 {{exception specification in explicit instantiation does not match instantiated one}}
+template void Foo(long a) throw(long, char);
+template void Foo(float a);
+#if __cplusplus >= 201103L
+// expected-error at +1 0-1 {{exception specification in explicit instantiation does not match instantiated one}}
+template void Foo(double a) noexcept;
+#endif
More information about the cfe-commits
mailing list