summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-01-04 23:14:16 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-01-04 23:14:16 +0000
commit1cf4541c4f3ae2f6eaadb6d7972cf8cc71118965 (patch)
treedf4d8e965429e869efc0446847b66f82039e72c3
parenta977582dead2c6696ff5e273efe84a3878bb6e61 (diff)
downloadbcm5719-llvm-1cf4541c4f3ae2f6eaadb6d7972cf8cc71118965.tar.gz
bcm5719-llvm-1cf4541c4f3ae2f6eaadb6d7972cf8cc71118965.zip
Bail out if we try to build a DeclRefExpr naming an invalid declaration.
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
-rw-r--r--clang/lib/Sema/SemaExpr.cpp3
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp2
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp4
-rw-r--r--clang/test/SemaCXX/conversion-function.cpp2
-rw-r--r--clang/test/SemaCXX/cxx1z-decomposition.cpp5
-rw-r--r--clang/test/SemaCXX/type-definition-in-specifier.cpp6
6 files changed, 15 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3c554c9a524..1509b22a9e5 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 5f769cc40de..1379440e8a0 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7262,6 +7262,8 @@ public:
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);
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 581a524339e..884f2f30c42 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -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 {
@@ -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 {
diff --git a/clang/test/SemaCXX/conversion-function.cpp b/clang/test/SemaCXX/conversion-function.cpp
index c725a0d5b7c..531de818b68 100644
--- a/clang/test/SemaCXX/conversion-function.cpp
+++ b/clang/test/SemaCXX/conversion-function.cpp
@@ -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;
}
diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp
index 735a9e1dfee..d457ace5d84 100644
--- a/clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -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
diff --git a/clang/test/SemaCXX/type-definition-in-specifier.cpp b/clang/test/SemaCXX/type-definition-in-specifier.cpp
index 74ba058b4f1..2da649fdb0b 100644
--- a/clang/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/clang/test/SemaCXX/type-definition-in-specifier.cpp
@@ -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}}
OpenPOWER on IntegriCloud