aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp18
-rw-r--r--test/CXX/temp/temp.decls/temp.mem/p5.cpp5
-rw-r--r--test/SemaTemplate/operator-template.cpp10
-rw-r--r--test/SemaTemplate/temp_arg_nontype.cpp2
4 files changed, 19 insertions, 16 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 03850bb760..93ea89d628 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -2589,7 +2589,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
Specialization = cast_or_null<FunctionDecl>(
SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner,
MultiLevelTemplateArgumentList(*DeducedArgumentList)));
- if (!Specialization)
+ if (!Specialization || Specialization->isInvalidDecl())
return TDK_SubstitutionFailure;
assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
@@ -2601,6 +2601,14 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
!Trap.hasErrorOccurred())
Info.take();
+ // There may have been an error that did not prevent us from constructing a
+ // declaration. Mark the declaration invalid and return with a substitution
+ // failure.
+ if (Trap.hasErrorOccurred()) {
+ Specialization->setInvalidDecl(true);
+ return TDK_SubstitutionFailure;
+ }
+
if (OriginalCallArgs) {
// C++ [temp.deduct.call]p4:
// In general, the deduction process attempts to find template argument
@@ -2619,14 +2627,6 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
}
}
- // There may have been an error that did not prevent us from constructing a
- // declaration. Mark the declaration invalid and return with a substitution
- // failure.
- if (Trap.hasErrorOccurred()) {
- Specialization->setInvalidDecl(true);
- return TDK_SubstitutionFailure;
- }
-
// If we suppressed any diagnostics while performing template argument
// deduction, and if we haven't already instantiated this declaration,
// keep track of these diagnostics. They'll be emitted if this specialization
diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
index a188f05d53..8bcd773ee9 100644
--- a/test/CXX/temp/temp.decls/temp.mem/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -63,7 +63,8 @@ struct X0 {
template<typename T> operator const T*() const {
T x = T();
- return x; // expected-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}}
+ return x; // expected-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}} \
+ // expected-error{{cannot initialize return object of type 'const int *' with an lvalue of type 'int'}}
}
};
@@ -72,7 +73,7 @@ template X0::operator const int*(); // expected-note{{'X0::operator const int *<
template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template}}
void test_X0(X0 x0, const X0 &x0c) {
- x0.operator const int*();
+ x0.operator const int*(); // expected-note{{in instantiation of function template specialization}}
x0.operator float *();
x0c.operator const char*();
}
diff --git a/test/SemaTemplate/operator-template.cpp b/test/SemaTemplate/operator-template.cpp
index 4300755cf7..777b0f5f42 100644
--- a/test/SemaTemplate/operator-template.cpp
+++ b/test/SemaTemplate/operator-template.cpp
@@ -2,7 +2,8 @@
// Make sure we accept this
template<class X>struct A{typedef X Y;};
-template<class X>bool operator==(A<X>,typename A<X>::Y);
+template<class X>bool operator==(A<X>,typename A<X>::Y); // expected-note{{candidate template ignored: failed template argument deduction}}
+
int a(A<int> x) { return operator==(x,1); }
int a0(A<int> x) { return x == 1; }
@@ -10,7 +11,8 @@ int a0(A<int> x) { return x == 1; }
// FIXME: the location information for the note isn't very good
template<class X>struct B{typedef X Y;};
template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
-expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
-expected-note{{in instantiation of function template specialization}}
-int a(B<int> x) { return operator==(&x,1); }
+// expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
+// expected-note{{in instantiation of function template specialization}} \
+// expected-note{{candidate template ignored: substitution failure [with X = int]}}
+int a(B<int> x) { return operator==(&x,1); } // expected-error{{no matching function for call to 'operator=='}}
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index 43fe38ba7c..747ddcc461 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -170,7 +170,7 @@ namespace pr6249 {
namespace PR6723 {
template<unsigned char C> void f(int (&a)[C]); // expected-note {{candidate template ignored}} \
- // expected-note{{candidate function [with C = '\x00'] not viable: no known conversion from 'int [512]' to 'int (&)[0]' for 1st argument}}
+ // expected-note{{substitution failure [with C = '\x00']}}
void g() {
int arr512[512];
f(arr512); // expected-error{{no matching function for call}}