diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11996,7 +11996,10 @@ /*TreatUnavailableAsInvalid=*/false); ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT); if (Result.isInvalid()) { - VDecl->setInvalidDecl(); + auto RecoveryExpr = + CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), Args); + if (RecoveryExpr.get()) + VDecl->setInit(RecoveryExpr.get()); return; } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2669,7 +2669,8 @@ // trying to determine whether this would be a valid range. if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) { AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false); - if (LoopVar->isInvalidDecl()) + if (LoopVar->isInvalidDecl() || + (LoopVar->getInit() && LoopVar->getInit()->containsErrors())) NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin); } } diff --git a/clang/test/AST/ast-dump-invalid-initialized.cpp b/clang/test/AST/ast-dump-invalid-initialized.cpp --- a/clang/test/AST/ast-dump-invalid-initialized.cpp +++ b/clang/test/AST/ast-dump-invalid-initialized.cpp @@ -11,9 +11,35 @@ // CHECK: `-VarDecl {{.*}} a3 'A' A a3 = garbage(); + // CHECK: `-VarDecl {{.*}} a4 'A' + A a4(1); + // CHECK: `-VarDecl {{.*}} a5 'A' + A a5{1}; + // CHECK: `-VarDecl {{.*}} a6 'A' + A a6(invalid()); + // CHECK: `-VarDecl {{.*}} a7 'A' + A a7{invalid()}; + + // CHECK: `-VarDecl {{.*}} a8 'A' + A a8 = 1; + // CHECK: `-VarDecl {{.*}} a9 'A' + A a9 = A(1); + // CHECK: `-VarDecl {{.*}} a10 'A' + A a10 = A(var); + // CHECK: `-VarDecl {{.*}} a11 'A' + A a11 = A{1}; + // CHECK: `-VarDecl {{.*}} a12 'A' + A a12 = {1}; + // CHECK: `-VarDecl {{.*}} invalid b1 'const A &' const A& b1; // CHECK: `-VarDecl {{.*}} invalid b2 'ForwardDecl' ForwardDecl b2; + // CHECK: `-VarDecl {{.*}} invalid b3 'auto' + auto b3 = garbage(); + // CHECK: `-VarDecl {{.*}} invalid b4 'auto' + auto b4 = A(1); + // CHECK: `-VarDecl {{.*}} invalid b5 'auto' + auto b5 = A{1}; } \ No newline at end of file diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -94,7 +94,28 @@ // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' struct Foo {} foo; -void test(int x) { +void test1(int x) { foo.abc; foo->func(x); -} \ No newline at end of file +} + +struct Bar { Bar(); }; +Bar createBar(int arg); +void test2() { + // CHECK: `-VarDecl {{.*}} bar1 'Bar' + // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors + // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'createBar' + Bar bar1 = createBar(); + // CHECK: `-VarDecl {{.*}} bar2 'Bar' + // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors + // CHECK-NEXT: `-InitListExpr + Bar bar2 = {1}; + // CHECK: `-VarDecl {{.*}} bar3 'Bar' + // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors + // CHECK-NEXT: `-IntegerLiteral + Bar bar3 = 1; + + // FIXME: would be nice to have recovery-expr for the failed ctor candidates + Bar foo1 = Bar(1); + Bar foo2 = Bar{1}; +} diff --git a/clang/test/CXX/special/class.copy/p11.0x.move.cpp b/clang/test/CXX/special/class.copy/p11.0x.move.cpp --- a/clang/test/CXX/special/class.copy/p11.0x.move.cpp +++ b/clang/test/CXX/special/class.copy/p11.0x.move.cpp @@ -32,7 +32,7 @@ }; }; extern DeletedNTVariant3 dntv3a(0); // expected-error {{no matching}} -extern DeletedNTVariant3 dntv3a(0); // expected-error {{no matching}} +extern DeletedNTVariant3 dntv3b(0); // expected-error {{no matching}} // -- a non-static data member of class type M (or array thereof) that cannot be // copied because overload resolution results in an ambiguity or a function diff --git a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp --- a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s -// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -frecovery-ast -verify %s +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -frecovery-ast -verify %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -frecovery-ast -verify %s struct pr12960 { int begin; diff --git a/clang/test/OpenMP/task_messages.cpp b/clang/test/OpenMP/task_messages.cpp --- a/clang/test/OpenMP/task_messages.cpp +++ b/clang/test/OpenMP/task_messages.cpp @@ -48,7 +48,6 @@ S1 s1; // expected-error@+1 2 {{call to deleted constructor of 'S1'}} #pragma omp task -// expected-note@+1 2 {{predetermined as a firstprivate in a task construct here}} ++s1; #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task default(shared) diff --git a/clang/test/SemaCXX/block-call.cpp b/clang/test/SemaCXX/block-call.cpp --- a/clang/test/SemaCXX/block-call.cpp +++ b/clang/test/SemaCXX/block-call.cpp @@ -10,8 +10,6 @@ int (^PFR) (int) = IFP; // expected-error {{cannot initialize a variable of type 'int (^)(int)' with an lvalue of type 'int (^)()'}} PFR = II; // OK - int (^IFP) () = PFR; // OK - const int (^CIC) () = IFP; // OK - initializing 'const int (^)()' with an expression of type 'int (^)()'}} @@ -32,8 +30,8 @@ int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-error {{cannot initialize a variable of type 'int (^)(int, char (^)(float))' with an lvalue of type}} - IPCC2 = 0; - IPCC2 = 1; + IPCC2 = 0; // OK - assign a nullptr to a pointer. + IPCC2 = 1; // expected-error {{invalid block pointer conversion assigning to 'int *(^)()' from 'int'}} int (^x)() = 0; int (^y)() = 3; // expected-error {{cannot initialize a variable of type 'int (^)()' with an rvalue of type 'int'}} int a = 1; diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion +// RUN: %clang_cc1 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fsyntax-only -fcxx-exceptions -verify -frecovery-ast -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion namespace StaticAssertFoldTest { diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp --- a/clang/test/SemaCXX/cxx11-crashes.cpp +++ b/clang/test/SemaCXX/cxx11-crashes.cpp @@ -67,7 +67,7 @@ struct S {}; // expected-note 3{{candidate}} void f() { S s(1, 2, 3); // expected-error {{no matching}} - for (auto x : s) { + for (auto x : s) { // expected-error {{invalid range expression of}} // We used to attempt to evaluate the initializer of this variable, // and crash because it has an undeduced type. const int &n(x); diff --git a/clang/test/SemaCXX/cxx2a-explicit-bool.cpp b/clang/test/SemaCXX/cxx2a-explicit-bool.cpp --- a/clang/test/SemaCXX/cxx2a-explicit-bool.cpp +++ b/clang/test/SemaCXX/cxx2a-explicit-bool.cpp @@ -124,7 +124,7 @@ A && a6{ 0}; A a7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}} -a0 = 0; +a0 = 0; // expected-error {{no viable overloaded '='}} a1 = { 0}; // expected-error {{no viable overloaded '='}} a2 = A( 0); a3 = A{ 0}; diff --git a/clang/test/SemaCXX/for-range-dereference.cpp b/clang/test/SemaCXX/for-range-dereference.cpp --- a/clang/test/SemaCXX/for-range-dereference.cpp +++ b/clang/test/SemaCXX/for-range-dereference.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -frecovery-ast -verify %s struct Data { }; struct T { Data *begin(); diff --git a/clang/test/SemaCXX/member-init.cpp b/clang/test/SemaCXX/member-init.cpp --- a/clang/test/SemaCXX/member-init.cpp +++ b/clang/test/SemaCXX/member-init.cpp @@ -64,7 +64,7 @@ template struct X { X() { - T* x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + T* x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} expected-warning {{unused variable}} } }; diff --git a/clang/test/SemaObjCXX/parameterized_classes_arc.mm b/clang/test/SemaObjCXX/parameterized_classes_arc.mm --- a/clang/test/SemaObjCXX/parameterized_classes_arc.mm +++ b/clang/test/SemaObjCXX/parameterized_classes_arc.mm @@ -13,7 +13,7 @@ @interface PC1 : NSObject - (T) get; -- (void) set: (T) v; +- (void) set: (T) v; // expected-note 4{{passing argument to}} @end void test1a(PC1<__weak id> *obj) { // expected-error {{type argument '__weak id' cannot be qualified with '__weak'}} @@ -34,17 +34,17 @@ // Test that this doesn't completely kill downstream type-checking. void test1d(PC1<__weak Forward*> *obj) { // expected-error {{type argument 'Forward *__weak' cannot be qualified with '__weak'}} Forward2 *x = [obj get]; // expected-error {{cannot initialize}} - [obj set: x]; + [obj set: x]; // expected-error {{cannot initialize a parameter of type 'Forward *' with an lvalue of type 'Forward2 *__strong'}} } void test1e(PC1<__strong Forward*> *obj) { // expected-error {{type argument 'Forward *__strong' cannot be qualified with '__strong'}} Forward2 *x = [obj get]; // expected-error {{cannot initialize}} - [obj set: x]; + [obj set: x]; // expected-error {{cannot initialize a parameter of type 'Forward *'}} } void test1f(PC1 *obj) { Forward2 *x = [obj get]; // expected-error {{cannot initialize}} - [obj set: x]; + [obj set: x]; // expected-error {{cannot initialize a parameter of type 'Forward *'}} } // Typedefs are fine, just silently ignore them. @@ -57,7 +57,7 @@ typedef __strong Forward *StrongForward; void test1h(PC1 *obj) { Forward2 *x = [obj get]; // expected-error {{cannot initialize}} - [obj set: x]; + [obj set: x]; // expected-error {{cannot initialize a parameter of type 'Forward *'}} } // These aren't really ARC-specific, but they're the same basic idea.