summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-05-09 03:31:27 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-05-09 03:31:27 +0000
commitfb98e7c13da639f34f34830a4e675367e0816cb6 (patch)
tree70e025e9b4a31559d1f061e72439b5414537ad3b /test
parent70cd574857c6023b8c60e325c4029a23f716c2dd (diff)
downloadclang-fb98e7c13da639f34f34830a4e675367e0816cb6.tar.gz
[c++20] Implement P0846R0: allow (ADL-only) calls to template-ids whose
template name is not visible to unqualified lookup. In order to support this without a severe degradation in our ability to diagnose typos in template names, this change significantly restructures the way we handle template-id-shaped syntax for which lookup of the template name finds nothing. Instead of eagerly diagnosing an undeclared template name, we now form a placeholder template-name representing a name that is known to not find any templates. When the parser sees such a name, it attempts to disambiguate whether we have a less-than comparison or a template-id. Any diagnostics or typo-correction for the name are delayed until its point of use. The upshot should be a small improvement of our diagostic quality overall: we now take more syntactic context into account when trying to resolve an undeclared identifier on the left hand side of a '<'. In fact, this works well enough that the backwards-compatible portion (for an undeclared identifier rather than a lookup that finds functions but no function templates) is enabled in all language modes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360308 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp60
-rw-r--r--test/CXX/drs/dr2xx.cpp7
-rw-r--r--test/CXX/drs/dr6xx.cpp9
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p5.cpp5
-rw-r--r--test/FixIt/typo-crash.cpp10
-rw-r--r--test/Misc/diag-template-diffing.cpp2
-rw-r--r--test/Modules/module-private.cpp4
-rw-r--r--test/Modules/submodules-merge-defs.cpp4
-rw-r--r--test/Parser/cxx-ambig-init-templ.cpp2
-rw-r--r--test/Parser/cxx-template-argument.cpp23
-rw-r--r--test/Parser/cxx-template-decl.cpp13
-rw-r--r--test/SemaCXX/alias-template.cpp7
-rw-r--r--test/SemaCXX/class.cpp2
-rw-r--r--test/SemaCXX/cxx2a-adl-only-template-id.cpp67
-rw-r--r--test/SemaCXX/destructor.cpp5
-rw-r--r--test/SemaCXX/invalid-member-expr.cpp5
-rw-r--r--test/SemaCXX/typo-correction.cpp2
-rw-r--r--test/SemaTemplate/dependent-base-classes.cpp2
-rw-r--r--test/SemaTemplate/dependent-template-recover.cpp10
-rw-r--r--test/SemaTemplate/rdar9173693.cpp7
-rw-r--r--test/SemaTemplate/recovery-crash.cpp4
21 files changed, 182 insertions, 68 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp
index abcc6eee94..0138b88578 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p3.cpp
@@ -1,25 +1,67 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s
-typedef int f;
+typedef int fn;
namespace N0 {
- struct A {
- friend void f();
+ struct A {
+ friend void fn();
void g() {
- int i = f(1);
+ int i = fn(1);
}
};
}
namespace N1 {
- struct A {
- friend void f(A &);
+ struct A {
+ friend void fn(A &);
operator int();
void g(A a) {
- // ADL should not apply to the lookup of 'f', it refers to the typedef
+ // ADL should not apply to the lookup of 'fn', it refers to the typedef
// above.
- int i = f(a);
+ int i = fn(a);
}
};
}
+
+namespace std_example {
+ int h; // expected-note {{non-template declaration}}
+ void g();
+#if __cplusplus <= 201703L
+ // expected-note@-2 {{non-template declaration}}
+#endif
+ namespace N {
+ struct A {};
+ template<class T> int f(T);
+ template<class T> int g(T);
+#if __cplusplus <= 201703L
+ // expected-note@-2 {{here}}
+#endif
+ template<class T> int h(T); // expected-note {{here}}
+ }
+
+ int x = f<N::A>(N::A());
+#if __cplusplus <= 201703L
+ // expected-warning@-2 {{C++2a extension}}
+#endif
+ int y = g<N::A>(N::A());
+#if __cplusplus <= 201703L
+ // expected-error@-2 {{'g' does not name a template but is followed by template arguments; did you mean 'N::g'?}}
+#endif
+ int z = h<N::A>(N::A()); // expected-error {{'h' does not name a template but is followed by template arguments; did you mean 'N::h'?}}
+}
+
+namespace AnnexD_example {
+ struct A {};
+ void operator<(void (*fp)(), A);
+ void f() {}
+ int main() {
+ A a;
+ f < a;
+#if __cplusplus > 201703L
+ // expected-error@-2 {{expected '>'}}
+#endif
+ (f) < a;
+ }
+}
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index b69c014b58..c7ffa77d30 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// PR13819 -- __SIZE_TYPE__ is incompatible.
typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}}
@@ -434,7 +435,7 @@ namespace dr239 { // dr239: yes
namespace dr241 { // dr241: yes
namespace A {
struct B {};
- template <int X> void f(); // expected-note 2{{candidate}}
+ template <int X> void f(); // expected-note 3{{candidate}}
template <int X> void g(B);
}
namespace C {
@@ -442,8 +443,8 @@ namespace dr241 { // dr241: yes
template <class T> void g(T t); // expected-note {{candidate}}
}
void h(A::B b) {
- f<3>(b); // expected-error {{undeclared identifier}}
- g<3>(b); // expected-error {{undeclared identifier}}
+ f<3>(b); // expected-error 0-1{{C++2a extension}} expected-error {{no matching}}
+ g<3>(b); // expected-error 0-1{{C++2a extension}}
A::f<3>(b); // expected-error {{no matching}}
A::g<3>(b);
C::f<3>(b); // expected-error {{no matching}}
diff --git a/test/CXX/drs/dr6xx.cpp b/test/CXX/drs/dr6xx.cpp
index b4247b2260..318096c299 100644
--- a/test/CXX/drs/dr6xx.cpp
+++ b/test/CXX/drs/dr6xx.cpp
@@ -1048,10 +1048,13 @@ namespace dr686 { // dr686: yes
template<struct R {} *> struct Y; // expected-error {{cannot be defined in a type specifier}}
}
-namespace dr687 { // dr687 still open
+namespace dr687 { // dr687 (9 c++20, but the issue is still considered open)
template<typename T> void f(T a) {
- // FIXME: This is valid in C++20.
- g<int>(a); // expected-error {{undeclared}} expected-error {{'('}}
+ // This is valid in C++20.
+ g<int>(a);
+#if __cplusplus <= 201703L
+ // expected-error@-2 {{C++2a extension}}
+#endif
// This is not.
template g<int>(a); // expected-error {{expected expression}}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p5.cpp b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
index ca1f9a391e..5f0c4547cf 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
@@ -8,7 +8,10 @@ namespace N {
};
}
-template class Z<int>; // expected-error{{explicit instantiation of non-template class 'Z'}}
+template class Z<int>; // expected-error{{explicit instantiation of undeclared template class 'Z'}}
+
+struct Q;
+template class Q<int>; // expected-error{{explicit instantiation of non-template class 'Q'}}
// FIXME: This example from the standard is wrong; note posted to CWG reflector
// on 10/27/2009
diff --git a/test/FixIt/typo-crash.cpp b/test/FixIt/typo-crash.cpp
index 4ea63c542a..5130e3e0e6 100644
--- a/test/FixIt/typo-crash.cpp
+++ b/test/FixIt/typo-crash.cpp
@@ -1,14 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// FIXME: The diagnostics and recovery here are very, very poor.
-
// PR10355
-template<typename T> void template_id1() { // expected-note {{'template_id1' declared here}} \
- // expected-note {{possible target for call}}
- template_id2<> t; // expected-error {{no template named 'template_id2'; did you mean 'template_id1'?}} \
- // expected-error {{expected ';' after expression}} \
- // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} \
- // expected-error {{use of undeclared identifier 't'}}
+template<typename T> void template_id1() {
+ template_id2<> t; // expected-error-re {{no template named 'template_id2'{{$}}}}
}
// FIXME: It would be nice if we could get this correction right.
diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp
index 5c85df434d..7d3e21533f 100644
--- a/test/Misc/diag-template-diffing.cpp
+++ b/test/Misc/diag-template-diffing.cpp
@@ -394,7 +394,7 @@ template<double* ...A> class class_ptrs {};
void set13(class_ptrs<&a13, &b13>) {}
void test13() {
set13(class_ptrs<&c13>());
- set13(class_ptrss<&a13, &b13, &d13>());
+ set13(class_ptrs<&a13, &b13, &d13>());
}
// CHECK-ELIDE-NOTREE: no matching function for call to 'set13'
// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'class_ptrs<&c13, (no argument)>' to 'class_ptrs<&a13, &b13>' for 1st argument
diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp
index 42ab185760..30957865d1 100644
--- a/test/Modules/module-private.cpp
+++ b/test/Modules/module-private.cpp
@@ -18,9 +18,7 @@ int test_broken() {
int *ip = 0;
f1(ip); // expected-error{{use of undeclared identifier 'f1'}}
- vector<int> vec; // expected-error{{use of undeclared identifier 'vector'}} \
- // expected-error{{expected '(' for function-style cast or type construction}} \
- // expected-error{{use of undeclared identifier 'vec'}}
+ vector<int> vec; // expected-error{{no template named 'vector'}}
VisibleStruct vs;
vs.field = 0; // expected-error{{no member named 'field' in 'VisibleStruct'}}
diff --git a/test/Modules/submodules-merge-defs.cpp b/test/Modules/submodules-merge-defs.cpp
index 795150208c..0f7637de57 100644
--- a/test/Modules/submodules-merge-defs.cpp
+++ b/test/Modules/submodules-merge-defs.cpp
@@ -29,7 +29,7 @@ B::Inner2 pre_bi; // expected-error +{{must be imported}}
// expected-note@defs.h:4 +{{here}}
// expected-note@defs.h:17 +{{here}}
void pre_bfi(B b) { // expected-error +{{must be imported}}
- b.f<int>(); // expected-error +{{}}
+ b.f<int>();
}
C_Base<1> pre_cb1; // expected-error +{{must be imported}}
@@ -48,7 +48,7 @@ int pre_e = E(0); // expected-error {{must be imported}}
// expected-note@defs.h:32 +{{here}}
int pre_ff = F<int>().f(); // expected-error +{{must be imported}}
-int pre_fg = F<int>().g<int>(); // expected-error +{{must be imported}} expected-error 2{{expected}}
+int pre_fg = F<int>().g<int>(); // expected-error +{{must be imported}}
// expected-note@defs.h:34 +{{here}}
G::A pre_ga // expected-error +{{must be imported}}
diff --git a/test/Parser/cxx-ambig-init-templ.cpp b/test/Parser/cxx-ambig-init-templ.cpp
index 89ed5e570b..a64760f3f4 100644
--- a/test/Parser/cxx-ambig-init-templ.cpp
+++ b/test/Parser/cxx-ambig-init-templ.cpp
@@ -31,7 +31,7 @@ struct S {
void f2a(
// T3<int> here is a parameter type, so must be declared before it is used.
- int k1 = c < b, T3 < int > x = 0 // expected-error {{unexpected end of default argument expression}}
+ int k1 = c < b, T3 < int > x = 0 // expected-error {{no template named 'T3'}}
);
template<typename, int=0> struct T3 { T3(int); operator int(); };
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
index 963356eaab..b3a9071785 100644
--- a/test/Parser/cxx-template-argument.cpp
+++ b/test/Parser/cxx-template-argument.cpp
@@ -60,33 +60,32 @@ namespace pr16225add {
template<int N1, int N2> struct ABC2 {};
template<class T1, typename T2> struct foo :
- UnknownBase<T1,T2> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<T1,T2> // expected-error {{no template named 'UnknownBase'}}
{ };
template<class T1, typename T2> struct foo2 :
- UnknownBase<T1,T2>, // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<T1,T2>, // expected-error {{no template named 'UnknownBase'}}
Known<T1> // expected-error {{too few template arguments for class template 'Known'}}
{ };
template<class T1, typename T2> struct foo3 :
- UnknownBase<T1,T2,ABC<T2,T1> > // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<T1,T2,ABC<T2,T1> > // expected-error {{no template named 'UnknownBase'}}
{ };
template<class T1, typename T2> struct foo4 :
- UnknownBase<T1,ABC<T2> >, // expected-error {{unknown template name 'UnknownBase'}} \
- // expected-error {{too few template arguments for class template 'ABC'}}
+ UnknownBase<T1,ABC<T2> >, // expected-error {{too few template arguments for class template 'ABC'}}
Known<T1> // expected-error {{too few template arguments for class template 'Known'}}
{ };
template<class T1, typename T2> struct foo5 :
- UnknownBase<T1,T2,ABC<T2,T1>> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<T1,T2,ABC<T2,T1>> // expected-error {{no template named 'UnknownBase'}}
#if __cplusplus <= 199711L
// expected-error@-2 {{use '> >'}}
#endif
{ };
template<class T1, typename T2> struct foo6 :
- UnknownBase<T1,ABC<T2,T1>>, // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<T1,ABC<T2,T1>>, // expected-error {{no template named 'UnknownBase'}}
#if __cplusplus <= 199711L
// expected-error@-2 {{use '> >'}}
#endif
@@ -94,32 +93,32 @@ namespace pr16225add {
{ };
template<class T1, typename T2, int N> struct foo7 :
- UnknownBase<T1,T2,(N>1)> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<T1,T2,(N>1)> // expected-error {{no template named 'UnknownBase'}}
{ };
template<class T1, typename T2> struct foo8 :
- UnknownBase<X<int,int>,X<int,int>> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<X<int,int>,X<int,int>> // expected-error {{no template named 'UnknownBase'}}
#if __cplusplus <= 199711L
// expected-error@-2 {{use '> >'}}
#endif
{ };
template<class T1, typename T2> struct foo9 :
- UnknownBase<Known<int,int>,X<int,int>> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<Known<int,int>,X<int,int>> // expected-error {{no template named 'UnknownBase'}}
#if __cplusplus <= 199711L
// expected-error@-2 {{use '> >'}}
#endif
{ };
template<class T1, typename T2> struct foo10 :
- UnknownBase<Known<int,int>,X<int,X<int,int>>> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<Known<int,int>,X<int,X<int,int>>> // expected-error {{no template named 'UnknownBase'}}
#if __cplusplus <= 199711L
// expected-error@-2 {{use '> >'}}
#endif
{ };
template<int N1, int N2> struct foo11 :
- UnknownBase<2<N1,N2<4> // expected-error {{unknown template name 'UnknownBase'}}
+ UnknownBase<2<N1,N2<4> // expected-error {{no template named 'UnknownBase'}}
{ };
}
diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp
index 9ad422e7ab..64c485fc0e 100644
--- a/test/Parser/cxx-template-decl.cpp
+++ b/test/Parser/cxx-template-decl.cpp
@@ -128,8 +128,13 @@ void f2() {
// PR3844
-template <> struct S<int> { }; // expected-error{{explicit specialization of non-template struct 'S'}}
-template <> union U<int> { }; // expected-error{{explicit specialization of non-template union 'U'}}
+template <> struct S<int> { }; // expected-error{{explicit specialization of undeclared template struct 'S'}}
+template <> union U<int> { }; // expected-error{{explicit specialization of undeclared template union 'U'}}
+
+struct SS;
+union UU;
+template <> struct SS<int> { }; // expected-error{{explicit specialization of non-template struct 'SS'}}
+template <> union UU<int> { }; // expected-error{{explicit specialization of non-template union 'UU'}}
namespace PR6184 {
namespace N {
@@ -230,11 +235,11 @@ struct base { };
struct t1 : base<int,
public: // expected-error {{expected expression}}
-}; // expected-error {{expected class name}}
+};
// expected-error@-1 {{expected '{' after base class list}}
struct t2 : base<int,
public // expected-error {{expected expression}}
-}; // expected-error {{expected class name}}
+};
// expected-error@-1 {{expected '{' after base class list}}
}
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index 0a92b9dd96..f41c3aa8bc 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -112,11 +112,8 @@ namespace StdExample {
template<typename T> using handler_t = void (*)(T);
extern handler_t<int> ignore;
extern void (*ignore)(int);
- // FIXME: we recover as if cell is an undeclared variable. the diagnostics are terrible!
- template<typename T> using cell = pair<T*, cell<T>*>; // expected-error {{use of undeclared identifier 'cell'}} \
- expected-error {{'T' does not refer to a value}} \
- expected-note {{declared here}} \
- expected-error {{expected ';' after alias declaration}}
+ // FIXME: we recover as if cell is an undeclared variable template
+ template<typename T> using cell = pair<T*, cell<T>*>; // expected-error {{use of undeclared identifier 'cell'}} expected-error {{expected expression}}
}
namespace Access {
diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp
index a3593689b5..b571370911 100644
--- a/test/SemaCXX/class.cpp
+++ b/test/SemaCXX/class.cpp
@@ -138,7 +138,7 @@ struct S
// Don't crash on this bogus code.
namespace pr6629 {
template<class T1, class T2> struct foo :
- bogus<foo<T1,T2> > // expected-error {{unknown template name 'bogus'}}
+ bogus<foo<T1,T2> > // expected-error {{no template named 'bogus'}}
{ };
template<> struct foo<unknown,unknown> { // expected-error {{undeclared identifier 'unknown'}}
diff --git a/test/SemaCXX/cxx2a-adl-only-template-id.cpp b/test/SemaCXX/cxx2a-adl-only-template-id.cpp
new file mode 100644
index 0000000000..4bd9a22f5f
--- /dev/null
+++ b/test/SemaCXX/cxx2a-adl-only-template-id.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+namespace N {
+ struct Q {};
+ template<typename> int f(Q);
+ template<int> int f(Q);
+ template<typename> int g(Q);
+ template<int> int g(Q);
+
+ template<int> int some_long_name(Q); // expected-note {{here}}
+}
+N::Q q;
+int g();
+
+int h();
+template<int> int h(...);
+int h(int);
+
+// OK, these find the above functions by ADL.
+int a = f<int>(q);
+int b(f<int>(q));
+int c(f<0>(q));
+int d = g<int>(q);
+
+int e = h<0>(q); // ok, found by unqualified lookup
+
+void fn() {
+ f<0>(q);
+ int f;
+ f<0>(q); // expected-error {{invalid operands to binary expression}}
+}
+
+void disambig() {
+ // FIXME: It's unclear whether ending the template argument at the > inside the ?: is correct here (see DR579).
+ f<true ? 1 > 2 : 3>(q); // expected-error {{expected ':'}} expected-note {{to match}} expected-error {{expected expression}}
+
+ f < 1 + 3 > (q); // ok, function call
+}
+
+bool typo(int something) { // expected-note 4{{declared here}}
+ // FIXME: We shouldn't suggest the N:: for an ADL call if the candidate can be found by ADL.
+ some_logn_name<3>(q); // expected-error {{did you mean 'N::some_long_name'?}}
+ somethign < 3 ? h() > 4 : h(0); // expected-error {{did you mean 'something'}}
+ // This is parsed as a comparison on the left of a ?: expression.
+ somethign < 3 ? h() + 4 : h(0); // expected-error {{did you mean 'something'}}
+ // This is parsed as an ADL-only template-id call.
+ somethign < 3 ? h() + 4 : h(0) >(0); // expected-error {{undeclared identifier 'somethign'}}
+ bool k(somethign < 3); // expected-error {{did you mean 'something'}}
+ return somethign < 3; // expected-error {{did you mean 'something'}}
+}
+
+// Ensure that treating undeclared identifiers as template names doesn't cause
+// problems.
+struct W<int> {}; // expected-error {{undeclared template struct 'W'}}
+X<int>::Y xy; // expected-error {{no template named 'X'}}
+void xf(X<int> x); // expected-error {{no template named 'X'}}
+struct A : X<int> { // expected-error {{no template named 'X'}}
+ A() : X<int>() {} // expected-error {{no template named 'X'}}
+};
+
+// Similarly for treating overload sets of functions as template names.
+struct g<int> {}; // expected-error {{'g' refers to a function template}}
+g<int>::Y xy; // expected-error {{no template named 'g'}} FIXME lies
+void xf(g<int> x); // expected-error {{variable has incomplete type 'void'}} expected-error 1+{{}} expected-note {{}}
+struct B : g<int> { // expected-error {{expected class name}}
+ B() : g<int>() {} // expected-error {{expected class member or base class name}}
+};
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index 00d2fc5529..2859953a02 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -99,7 +99,7 @@ struct Y {
namespace PR6421 {
class T; // expected-note{{forward declaration}}
- class QGenericArgument // expected-note{{declared here}}
+ class QGenericArgument
{
template<typename U>
void foo(T t) // expected-error{{variable has incomplete type}}
@@ -108,8 +108,7 @@ namespace PR6421 {
void disconnect()
{
T* t;
- bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
- // expected-error{{does not refer to a value}}
+ bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}}
}
};
}
diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp
index fd50d328da..920d92380e 100644
--- a/test/SemaCXX/invalid-member-expr.cpp
+++ b/test/SemaCXX/invalid-member-expr.cpp
@@ -53,7 +53,10 @@ namespace test3 {
namespace rdar11293995 {
struct Length {
- explicit Length(PassRefPtr<CalculationValue>); // expected-error {{no template named 'PassRefPtr}} expected-error {{undeclared identifier 'CalculationValue'}}
+ // FIXME: We try to annotate the template-id here during tentative parsing,
+ // and fail, then try again during the actual parse. This results in the same
+ // diagnostic being produced twice. :(
+ explicit Length(PassRefPtr<CalculationValue>); // expected-error 2{{undeclared identifier 'CalculationValue'}}
};
struct LengthSize {
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index ddd43c0809..33dea4d36b 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -438,7 +438,7 @@ namespace PR17394 {
long zzzzzzzzzz;
};
class B : private A {};
- B zzzzzzzzzy<>; // expected-error {{expected ';' after top level declarator}}{}
+ B zzzzzzzzzy<>; // expected-error {{template specialization requires 'template<>'}} expected-error {{no variable template matches specialization}}
}
namespace correct_fields_in_member_funcs {
diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp
index 6d342f984d..bb4f3ca1f1 100644
--- a/test/SemaTemplate/dependent-base-classes.cpp
+++ b/test/SemaTemplate/dependent-base-classes.cpp
@@ -9,7 +9,7 @@ template<typename T, typename U>
struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
template<typename T>
-struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
+struct X2 : vector<T> { }; // expected-error{{no template named 'vector'}}
namespace PR6031 {
template<typename T>
diff --git a/test/SemaTemplate/dependent-template-recover.cpp b/test/SemaTemplate/dependent-template-recover.cpp
index 37a8faa705..90ba3cd899 100644
--- a/test/SemaTemplate/dependent-template-recover.cpp
+++ b/test/SemaTemplate/dependent-template-recover.cpp
@@ -7,7 +7,7 @@ struct X {
t->operator+<U const, 1>(1); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
t->f1<int const, 2>(1); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
- t->f1<3, int const>(1); // expected-error{{missing 'template' keyword prior to dependent template name 'f1'}}
+ t->f1<3, int const>(1); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
@@ -15,7 +15,7 @@ struct X {
(*t).f2<N>(); // expected-error{{missing 'template' keyword prior to dependent template name 'f2'}}
(*t).f2<0>(); // expected-error{{missing 'template' keyword prior to dependent template name 'f2'}}
T::f2<0>(); // expected-error{{missing 'template' keyword prior to dependent template name 'f2'}}
- T::f2<0, int>(0); // expected-error{{missing 'template' keyword prior to dependent template name 'f2'}}
+ T::f2<0, int>(0); // expected-error{{use 'template' keyword to treat 'f2' as a dependent template name}}
T::foo<N < 2 || N >= 4>(); // expected-error{{missing 'template' keyword prior to dependent template name 'foo'}}
@@ -24,7 +24,7 @@ struct X {
T::foo<T::bar < 1>(); // expected-error{{missing 'template' keyword prior to dependent template name 'foo'}}
T::foo < T::bar<1>(); // expected-error{{missing 'template' keyword prior to dependent template name 'bar'}}
- // Prefer to diagonse a missing 'template' keyword rather than finding a non-template name.
+ // Prefer to diagnose a missing 'template' keyword rather than finding a non-template name.
xyz < T::foo < 1 > (); // expected-error{{missing 'template' keyword prior to dependent template name 'foo'}}
T::foo < xyz < 1 > (); // expected-error{{missing 'template' keyword prior to dependent template name 'foo'}}
@@ -83,12 +83,12 @@ template<int N, typename T> void f(T t) {
T::g<mb>(0);
// ... but this one must be a template-id.
- T::g<mb, int>(0); // expected-error {{missing 'template' keyword prior to dependent template name 'g'}}
+ T::g<mb, int>(0); // expected-error {{use 'template' keyword to treat 'g' as a dependent template name}} expected-error {{no matching function}}
}
struct Y {
template <int> void f(int);
- template <int = 0> static void g(int); // expected-warning 0-1{{extension}}
+ template <int = 0> static void g(int); // expected-warning 0-1{{extension}} expected-note {{candidate}}
};
void q() { void (*p)(int) = Y::g; }
template void f<0>(Y); // expected-note {{in instantiation of}}
diff --git a/test/SemaTemplate/rdar9173693.cpp b/test/SemaTemplate/rdar9173693.cpp
index 86b49545a3..ed09a64a0d 100644
--- a/test/SemaTemplate/rdar9173693.cpp
+++ b/test/SemaTemplate/rdar9173693.cpp
@@ -2,5 +2,8 @@
// <rdar://problem/9173693>
template< bool C > struct assert { };
-template< bool > struct assert_arg_pred_impl { }; // expected-note 3 {{declared here}}
-template< typename Pred > assert<false> assert_not_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type ); // expected-error 5 {{}}
+// FIXME: We diagnose the same problem multiple times here because we have no
+// way to indicate in the token stream that we already tried to annotate a
+// template-id and we failed.
+template< bool > struct assert_arg_pred_impl { }; // expected-note 4 {{declared here}}
+template< typename Pred > assert<false> assert_not_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type ); // expected-error 6 {{}}
diff --git a/test/SemaTemplate/recovery-crash.cpp b/test/SemaTemplate/recovery-crash.cpp
index c8e783f47b..ec44747ce5 100644
--- a/test/SemaTemplate/recovery-crash.cpp
+++ b/test/SemaTemplate/recovery-crash.cpp
@@ -28,12 +28,12 @@ namespace PR16134 {
namespace PR16225 {
template <typename T> void f();
template <typename C> void g(C*) {
- struct LocalStruct : UnknownBase<Mumble, C> { }; // expected-error {{unknown template name 'UnknownBase'}} \
- // expected-error {{use of undeclared identifier 'Mumble'}}
+ struct LocalStruct : UnknownBase<Mumble, C> { }; // expected-error {{use of undeclared identifier 'Mumble'}}
f<LocalStruct>();
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses local type 'LocalStruct'}}
#endif
+ struct LocalStruct2 : UnknownBase<C> { }; // expected-error {{no template named 'UnknownBase'}}
}
struct S;
void h() {