forked from OSchip/llvm-project
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:
parent
9bad2fb378
commit
1ababa63de
|
@ -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());
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue