Continue to instantiate sub-statements in a CompoundStmt as long as

we don't see a DeclStmt (failure to instantiate which generally causes
panic).

llvm-svn: 112282
This commit is contained in:
John McCall 2010-08-27 19:56:05 +00:00
parent 9bad2fb378
commit 1ababa63de
6 changed files with 64 additions and 13 deletions

View File

@ -3440,18 +3440,30 @@ template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
bool IsStmtExpr) {
bool SubStmtInvalid = false;
bool SubStmtChanged = false;
ASTOwningVector<Stmt*> 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<DeclStmt>(*B))
return StmtError();
// Otherwise, just keep processing substatements and fail later.
SubStmtInvalid = true;
continue;
}
SubStmtChanged = SubStmtChanged || Result.get() != *B;
Statements.push_back(Result.takeAs<Stmt>());
}
if (SubStmtInvalid)
return StmtError();
if (!getDerived().AlwaysRebuild() &&
!SubStmtChanged)
return SemaRef.Owned(S->Retain());

View File

@ -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 <class F> void bind(F f); // expected-note 6 {{candidate template ignored}}
template <class F> void bind(F f); // expected-note 12 {{candidate template ignored}}
template <class F, class T> void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}}
template <class F> 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 T> 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<int>::test0b(); // expected-note {{in instantiation}}
}

View File

@ -24,7 +24,7 @@ template<typename T, typename U, int N, int M>
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);
}
};

View File

@ -63,7 +63,11 @@ template struct Conditional0<int, int, int>;
template<typename T>
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}}
}
};

View File

@ -115,7 +115,7 @@ template<typename T>
struct Delete0 {
void f(T t) {
delete t; // expected-error{{cannot delete}}
::delete [] t;
::delete [] t; // expected-error{{cannot delete}}
}
};

View File

@ -72,7 +72,7 @@ template<typename T, typename U, typename V> 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<typename T> 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);