Skip to content

Commit

Permalink
Bail out if we try to build a DeclRefExpr naming an invalid declaration.
Browse files Browse the repository at this point in the history
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.

llvm-svn: 291030
  • Loading branch information
zygoloid committed Jan 4, 2017
1 parent a977582 commit 1cf4541
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 7 deletions.
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2777,6 +2777,9 @@ bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS,
/// 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;
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7262,6 +7262,8 @@ class TransformTypos : public TreeTransform<TransformTypos> {
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);
Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/constant-expression-cxx11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,7 @@ namespace AfterError {
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 {
Expand Down Expand Up @@ -2030,7 +2030,7 @@ namespace PR21786 {

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 {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/conversion-function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ namespace PR18234 {
#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;
}
5 changes: 5 additions & 0 deletions clang/test/SemaCXX/cxx1z-decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,9 @@ void for_range() {
}
}

int error_recovery() {
auto [foobar]; // expected-error {{requires an initializer}}
return foobar_; // expected-error {{undeclared identifier 'foobar_'}}
}

// FIXME: by-value array copies
6 changes: 2 additions & 4 deletions clang/test/SemaCXX/type-definition-in-specifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,8 @@ struct s19018b {
};

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}}
Expand Down

0 comments on commit 1cf4541

Please sign in to comment.