summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/DeclBase.cpp14
-rw-r--r--clang/test/SemaCXX/cxx1z-decomposition.cpp12
2 files changed, 25 insertions, 1 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 5d130acfbed..8deef3343db 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -109,12 +109,24 @@ const char *Decl::getDeclKindName() const {
void Decl::setInvalidDecl(bool Invalid) {
InvalidDecl = Invalid;
assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
- if (Invalid && !isa<ParmVarDecl>(this)) {
+ if (!Invalid) {
+ return;
+ }
+
+ if (!isa<ParmVarDecl>(this)) {
// Defensive maneuver for ill-formed code: we're likely not to make it to
// a point where we set the access specifier, so default it to "public"
// to avoid triggering asserts elsewhere in the front end.
setAccess(AS_public);
}
+
+ // Marking a DecompositionDecl as invalid implies all the child BindingDecl's
+ // are invalid too.
+ if (DecompositionDecl *DD = dyn_cast<DecompositionDecl>(this)) {
+ for (BindingDecl *Binding : DD->bindings()) {
+ Binding->setInvalidDecl();
+ }
+ }
}
const char *DeclContext::getDeclKindName() const {
diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp
index 762dd7b94de..735a9e1dfee 100644
--- a/clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -53,4 +53,16 @@ void bitfield() {
auto &[p, q, r] = a; // expected-error {{decomposes into 2 elements, but 3 names were provided}}
}
+void for_range() {
+ int x = 1;
+ for (auto[a, b] : x) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
+ a++;
+ }
+
+ int y[5];
+ for (auto[c] : y) { // expected-error {{cannot decompose non-class, non-array type 'int'}}
+ c++;
+ }
+}
+
// FIXME: by-value array copies
OpenPOWER on IntegriCloud