diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a796f2eaff94ed89f5ab1698d7c4f539f817eeee..dbc02d8727207823013af573cfdd1f06f42f3e35 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3440,18 +3440,30 @@ template StmtResult TreeTransform::TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr) { + bool SubStmtInvalid = false; bool SubStmtChanged = false; ASTOwningVector Statements(getSema()); for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end(); B != BEnd; ++B) { StmtResult Result = getDerived().TransformStmt(*B); - if (Result.isInvalid()) - return StmtError(); + if (Result.isInvalid()) { + // Immediately fail if this was a DeclStmt, since it's very + // likely that this will cause problems for future statements. + if (isa(*B)) + return StmtError(); + + // Otherwise, just keep processing substatements and fail later. + SubStmtInvalid = true; + continue; + } SubStmtChanged = SubStmtChanged || Result.get() != *B; Statements.push_back(Result.takeAs()); } + if (SubStmtInvalid) + return StmtError(); + if (!getDerived().AlwaysRebuild() && !SubStmtChanged) return SemaRef.Owned(S->Retain()); diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index 83823f69c6373be2878fe0c6e2aa1054dd511a4b..795c0b95efd6d9714f3a39b2d3537f49134e1e46 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -179,13 +179,11 @@ namespace rdar8358512 { // We can't call this with an overload set because we're not allowed // to look into overload sets unless the parameter has some kind of // function type. - template void bind(F f); // expected-note 6 {{candidate template ignored}} + template void bind(F f); // expected-note 12 {{candidate template ignored}} template void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}} template void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}} struct A { - void member(); - void nonstat(); void nonstat(int); @@ -234,4 +232,41 @@ namespace rdar8358512 { } }; }; + + template class B { + void nonstat(); + void nonstat(int); + + void mixed(); + static void mixed(int); + + static void stat(); + static void stat(int); + + // None of these can be diagnosed yet, because the arguments are + // still dependent. + void test0a() { + bind(&nonstat); + bind(&B::nonstat); + + bind(&mixed); + bind(&B::mixed); + + bind(&stat); + bind(&B::stat); + } + + void test0b() { + bind(&nonstat); // expected-error {{no matching function for call}} + bind(&B::nonstat); // expected-error {{no matching function for call}} + + bind(&mixed); // expected-error {{no matching function for call}} + bind(&B::mixed); // expected-error {{no matching function for call}} + + bind(&stat); // expected-error {{no matching function for call}} + bind(&B::stat); // expected-error {{no matching function for call}} + } + }; + + template void B::test0b(); // expected-note {{in instantiation}} } diff --git a/clang/test/SemaTemplate/instantiate-clang.cpp b/clang/test/SemaTemplate/instantiate-clang.cpp index cef2b7090bf2e6d59b311196592a44442ec28e1b..34d68c4e59fd5bcfa1cd39a57d5da478bb3027ba 100644 --- a/clang/test/SemaTemplate/instantiate-clang.cpp +++ b/clang/test/SemaTemplate/instantiate-clang.cpp @@ -24,7 +24,7 @@ template struct ShuffleVector0 { void f(T t, U u, double2 a, double2 b) { (void)__builtin_shufflevector(t, u, N, M); // expected-error{{index}} - (void)__builtin_shufflevector(a, b, N, M); + (void)__builtin_shufflevector(a, b, N, M); // expected-error{{index}} (void)__builtin_shufflevector(a, b, 2, 1); } }; diff --git a/clang/test/SemaTemplate/instantiate-expr-3.cpp b/clang/test/SemaTemplate/instantiate-expr-3.cpp index d506b19a7a9721d42a3b7c548261f9c1cb19336f..ca88b00300dcfa7de409a6543a96b72b5819ebd9 100644 --- a/clang/test/SemaTemplate/instantiate-expr-3.cpp +++ b/clang/test/SemaTemplate/instantiate-expr-3.cpp @@ -63,7 +63,11 @@ template struct Conditional0; template struct StatementExpr0 { void f(T t) { - (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{contextually convertible}} + (void)({ + if (t) // expected-error{{contextually convertible}} + t = t + 17; + t + 12; // expected-error{{invalid operands}} + }); } }; @@ -106,8 +110,8 @@ struct VaArg1 { VaList va; __builtin_va_start(va, n); // expected-error{{int}} for (int i = 0; i != n; ++i) - (void)__builtin_va_arg(va, ArgType); - __builtin_va_end(va); + (void)__builtin_va_arg(va, ArgType); // expected-error{{int}} + __builtin_va_end(va); // expected-error{{int}} } }; diff --git a/clang/test/SemaTemplate/instantiate-expr-4.cpp b/clang/test/SemaTemplate/instantiate-expr-4.cpp index 8cd7342e98ebc6e9b46eeef05e1a2dd7239e39bd..adae1da26aaf5b35a144c794ac14bb5bd0fe3b43 100644 --- a/clang/test/SemaTemplate/instantiate-expr-4.cpp +++ b/clang/test/SemaTemplate/instantiate-expr-4.cpp @@ -115,7 +115,7 @@ template struct Delete0 { void f(T t) { delete t; // expected-error{{cannot delete}} - ::delete [] t; + ::delete [] t; // expected-error{{cannot delete}} } }; diff --git a/clang/test/SemaTemplate/instantiate-function-1.cpp b/clang/test/SemaTemplate/instantiate-function-1.cpp index a293e9a788decad494dd5972f449e1b0985cb79d..651c02c6cdcf57c7c359d38a1dcd9ac6d3934b56 100644 --- a/clang/test/SemaTemplate/instantiate-function-1.cpp +++ b/clang/test/SemaTemplate/instantiate-function-1.cpp @@ -72,7 +72,7 @@ template struct X6 { if (T x = t) { t = x; } - return v; + return v; // expected-error{{cannot initialize return object of type}} } }; @@ -178,10 +178,10 @@ template struct IndirectGoto0 { prior: T prior_label; - prior_label = &&prior; + prior_label = &&prior; // expected-error{{assigning to 'int'}} T later_label; - later_label = &&later; + later_label = &&later; // expected-error{{assigning to 'int'}} later: (void)(1+1);