Most code paths would already bail out in this case, but certain paths,
particularly overload resolution and typo correction, would not. Carrying on
with an invalid declaration could in some cases result in crashes due to
downstream code relying on declaration invariants that are not necessarily
met for invalid declarations, and in other cases just resulted in undesirable
follow-on diagnostics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291030
91177308-0d34-0410-b5e6-
96231b3b80d8
/// were not overloaded, and it doesn't promise that the declaration
/// will in fact be used.
static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
+ if (D->isInvalidDecl())
+ return true;
+
if (isa<TypedefNameDecl>(D)) {
S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName();
return true;
while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
if (InitDecl && TC.getFoundDecl() == InitDecl)
continue;
+ // FIXME: If we would typo-correct to an invalid declaration, it's
+ // probably best to just suppress all errors from this typo correction.
ExprResult NE = State.RecoveryHandler ?
State.RecoveryHandler(SemaRef, E, TC) :
attemptRecovery(SemaRef, *State.Consumer, TC);
constexpr int error() { // expected-error {{no return statement}}
return foobar; // expected-error {{undeclared identifier}}
}
- constexpr int k = error(); // expected-error {{must be initialized by a constant expression}}
+ constexpr int k = error();
}
namespace std {
namespace PR21859 {
constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}}
- constexpr int Var = Fun(); // expected-error {{constexpr variable 'Var' must be initialized by a constant expression}}
+ constexpr int Var = Fun();
}
struct InvalidRedef {
#endif
} a;
A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}
- A::E e = a; // expected-note {{here}}
+ A::E e = a;
bool k1 = e == A::e; // expected-error {{no member named 'e'}}
bool k2 = e.n == 0;
}
}
}
+int error_recovery() {
+ auto [foobar]; // expected-error {{requires an initializer}}
+ return foobar_; // expected-error {{undeclared identifier 'foobar_'}}
+}
+
// FIXME: by-value array copies
};
struct pr18963 {
- short bar5 (struct foo4 {} bar2); // expected-error{{'foo4' cannot be defined in a parameter type}} \
- // expected-note{{declared here}}
-
- long foo5 (float foo6 = foo4); // expected-error{{'foo4' does not refer to a value}}
+ short bar5 (struct foo4 {} bar2); // expected-error{{'foo4' cannot be defined in a parameter type}}
+ long foo5 (float foo6 = foo4);
};
// expected-error@+2 {{cannot be defined in a parameter type}}